Crokinole Club
Choose how you'd like to play
Coming soon
This mode is on its way in a future update.
Skills Competition
Choose a challenge
Skills Competition BuilderBuild your own challenge rounds and competitions, on any board
Skills Competition
Build, import, and play your own challenge rounds and competitions
Create a Skills Challenge RoundLay out discs on a blank board and set scoring conditions
Create a Skills CompetitionName it and assemble an ordered list of Rounds
Import from FileLoad a Round or Competition someone shared with you
Rounds
Folders:
Competitions
Victory Conditions & Description
Folders:
Tags:
Zoom
Show:
Drag a coloured disc onto the board. Hover one disc over another for about a second to stack them. The board is shown from the same angle you'll actually shoot from. Scroll wheel / pinch / Z·X·R keys to zoom.
The shooter takes this many shots in a row (board resets fresh each time) before the turn passes on.
Default: only your single best-scoring condition counts per shot. Turn this on to add up every condition a shot meets instead — e.g. 1 point for each of the alleys you clear.
Scoring Conditions
Resource Links (up to 5 — open in a new tab)
Available Rounds
This Competition (in order)
Practice Games & Drills
Set up a board and practice against it, on your own, any time
Create a Practice GameLay out discs on a blank board and start shooting
Practice Games & Drills
Game Settings
Board look, general options, and physics tuning — applies to every game mode.
Version: — build
Live preview — updates as you pick colours below.
Save the Physics Playground sliders below as a named preset to switch between different feels later (e.g. "Slick Table" vs. "Sticky Table"); "Default (shipped)" is always available and can't be deleted.
On a phone or tablet that supports it, gives a short vibration buzz when a disc drops into the 20 or the -10 hole (a quick double-buzz for a 20, a faster triple-buzz for a -10, so they feel different without looking) — also used for the Reposition-armed confirmation while aiming. Has no effect on a desktop/laptop or a device without vibration support.
When on, shows the exact "Power Level" your shot is currently set to — the real inches it will travel unobstructed (the smallest possible shot is Power Level 0.25", and a shot that just reaches the far backboard is Power Level 26") — right on the board next to your disc as you pull back or flick, on whichever side keeps it visible.
When on, the camera automatically re-frames itself at the start of every shot to a level that fits every disc currently on the board (with a little breathing room around them) plus the full back line the shooter is aiming from — so you never have to manually zoom out to see what you're shooting at or around.
Plays a little grab-wax-place sound effect each time a disc is set on the back line to aim (human or AI). Off by default. Doesn't affect any other sound — knocks, sinks, wall hits, and everything else always play.
A few scattered grains of wax/salt dust on the board and in the gutters, like a real shuffleboard-style board. Density controls how much shows up ("None" turns the effect off). Gutter Salt adds an extra concentrated patch in the middle of each player's own shooting area — turn it off to keep the gutters at just the same light dusting as the rest of the board. Grain Brightness and Colour control how visible the individual grains themselves are. "Auto" (the default) automatically picks whichever of Light Yellow, Bright White, or Gold shows up best against your board's own veneer/gutter colour, plus a brightness boost if even the best of those three still comes up short, so the grains stay visible no matter what board you're on — pick a fixed colour instead if you'd rather it never changes.
How thick the discs' own paint looks. Higher = stronger, more solid colour with less wood grain showing through and lighter edge shading; lower = more of the wood grain shows through and the curved-edge shading gets darker/more pronounced, closer to bare unpainted wood. 100% matches the original look.
How bright the light-catching highlight on the disc's rim is (the lighter band you see near the top edge of a disc). 100% is the original look; drag it down to fade that highlight out — 0% removes it entirely, leaving just the disc's own flat colour all the way around.
Pull & Release: press the disc and pull back — direction and pull distance set aim and power, like a slingshot, release to fire. Flick: swipe your finger (or mouse) in the direction you want the disc to go — the length and speed of the swipe set the power. Good for mouse, Flick often feels more natural on a phone or tablet.
Controls the little fading motion-trail dots left behind a disc while it slides during a shot — green for a soft shot, red for a hard one. "All Discs" shows them behind every disc that moves (the shooter and anything it strikes) — the default. "Shooting Disc Only" limits them to just the disc that was actually shot. "Don't Show" turns the effect off entirely (the three sliders below then have nothing to affect).
650ms
How long each dot lingers on screen before it's fully faded away. Lower = a quicker fade (a shorter, snappier trail); higher = dots linger longer (a longer trail).
2.2
Gap between dropped dots along the disc's path — this is a distance, not a count, so LOWER actually means MORE dots (a denser trail); higher means fewer, more spread out.
1.0%
How large each individual trail dot is drawn, as a percentage of the whole board's width.
Every factor below is a real, live number the computer players actually use when deciding what shot to take — nothing here is just descriptive. Difficulty mainly comes from HOW MANY of these a level bothers weighing (Easy ignores opponents entirely) and how shaky its own execution is, not a separate "skill" dial. Changes apply to the very next computer shot and are saved, so they stick around after a reload — "Reset to Defaults" below undoes everything on this whole panel at once.
Save the difficulty table and every factor below as a named profile you can switch back to later, edit the name of, or delete. "Default (shipped)" is always available and can't be deleted.
Live-tunes the judgment-call odds and thresholds the physics engine uses — wax kicks, backboard rebounds, hole capture/lip-out, dislodging a sunk disc, edge wobble, board speed, peg/backboard restitution, spin transfer, follow-through wiggle room, and stack-collapse thresholds — for experimenting with the feel of shots. Changes here apply immediately to the very next shot and are saved, surviving a page refresh. Use the Physics Tuning Preset picker above to save the current sliders as a named preset you can switch back to later, or "Reset to Defaults" below to return to the game's shipped settings. The force%-to-launch-speed curve and hole-capture rule are a full real-world recalibration (task #124 removed the two earlier "Original"/"2nd Generation" curves this game briefly shipped with): exact measured board/disc proportions, a power meter where 75% of the draw reaches the far shooting line (24") and 100% reaches a rare 12-foot blast, and a much stricter, real-world-calibrated hole capture rule (roughly 50% coverage right as a shot reaches the hole to sink, a brief window just past that where it wobbles across instead, and a clean sail-over beyond that) — sinking the 20 takes genuine touch, not just aim.
build 2026-09-15 23:58 MDT (Phase 136 — Settings cleanup (user request): removed the "Physics Model" V2/V3 toggle from Settings entirely, along with attemptHoleV2 (the old discrete 9-stage hole-capture model it switched to) and PHYSICS_MODEL/setPhysicsModel/syncPhysicsModelUI; attemptHole is now a thin pass-through straight to attemptHoleV3, which has been the only hole-capture model actually reachable since Phase 115's default flip and is now the only one that exists. Investigated whether V3 uses any Physics Playground settings before touching that panel — it does (its own 12 v3*-prefixed tunables plus several shared "look and feel" fields like gravBendMaxDeg/holeLipWobbleFrames/jumpFrames), so the Physics Playground stays; only the handful of fields attemptHoleV2 alone ever read (the old 9-stage ladder's capture chances/coverage thresholds, plus the already-fully-dead holeLipWobbleDeg) were pruned from both PHYSICS_TUNABLES_V2 and the Playground field list. Removed "Show tray-corner shortcuts" and all of its code (the 4 corner divs, their CSS/clip-paths, renderTrayCorners and every call site) — a redundant tray-click shortcut with no other effect on gameplay. Removed "Show Game Instructions/Help" and its whole feature (GAME_SETTINGS/GAME_SETTINGS_FIELDS/renderGameSettingsRows, renderPlayInstructions, the #play-instructions element and its CSS) — Game Settings had no other fields left in it. With the "Game Settings" section now otherwise empty, the standalone cards that used to sit as bare siblings below it (Physics Tuning Preset [renamed from "Physics Model" now that there's no engine choice left to name — the physicsPresetManager/toasts were renamed to match], Tactile Feedback, Show Power Level, Auto Zoom, Waxing Sounds, Wax/Salt Texture, Disc Paint Density, Disc Highlight Strength, Shooting Input, Shot Trails) were moved inside it, so every remaining game-wide toggle actually lives under the "Game Settings" header as its name implies. Customize Game Board, AI Decision Factors, and Physics Playground remain their own separate sections. Verified via node --check on both script blocks, a full sweep for dangling references to every removed symbol, and Playwright regression runs (disc highlight, paint density, auto zoom, wax texture, plus a dedicated hole-capture repeat-trial test) — all pass with zero page errors.)
build 2026-09-15 02:41 MDT (Phase 125: four bug reports/requests from one message, sent right after seeing the shipped Phase 124 build, plus a real saved-match export and screenshots. First: "the area where the play-by-play is listed should not be see thru when a game starts. make it brown like the background behind the scoring" — the #info-overlay wrapper (Phase 118's floating-on-top-of-the-board architecture) has no background of its own, relying entirely on its children's own solid fills; at the >=760px side-by-side layout, .play-panels' align-items:flex-start let the shorter .play-log column's own background stop short of its taller .play-status-col sibling, leaving a gap that visibly showed the live board bleeding through underneath. Fixed by switching to align-items:stretch so both columns' backgrounds always reach the row's full height. Second: "the auto zoom needs to ignore discs in the gutter. Also it should leave more room...at the bottom...to allow for easy pulling back to aim and adjust force." computeAutoZoomFrame's disc-inclusion loop now skips any disc whose distance from center exceeds BAND_OUTER (the real playing surface's outer edge) before folding it into the bounding box, so a ditched disc no longer forces a wider/looser frame to keep it in view. The bottom margin (padBottom) is reworked from a small fixed cosmetic buffer into Math.max(the old cosmetic term, AIM_V2_MAX_DRAG + a small buffer) — since the Pull & Release gesture's finger travel maps 1:1 in board units to force% via the same inverse-transform math clientToRel already uses, reserving that many CONTENT units below the shooter's disc guarantees, at whatever scale the frame ends up fit to, that many real screen pixels of headroom for a full 0-100% pull, self-consistently regardless of zoom level rather than a fixed guess tuned for only one. Third, from the user's own uploaded match export (Round 1 Shot 12) and screenshot: "the black disc slowly slides overtop of the green disc in the hole. This is not possible...it still bumps discs back...I thought we had addressed this." A similar same-physics-step gap WAS fixed before (task #89's freshObstacles re-check) — this was a different root cause entirely: SUNK_OBSTACLE_R (the collision footprint of an already-sunk disc) was only DISC_R*0.5, on the old assumption that "only about half of it still pokes up above the table." The user pointed out the 20-hole (and the other scoring holes) is only a shallow 1/4-depth pocket, so almost the FULL disc still sits proud and needs to present essentially its real visual size as an obstacle. SUNK_OBSTACLE_R is now the full DISC_R — verified with a direct physics-engine test reproducing the scenario (a moving disc below dislodge speed now separates by more than a full disc-width instead of overlapping ~50%) — while the existing dislodge mechanic (a hit at or above PHYSICS_DERIVED_V2.dislodgeSpeed still pops the sunk disc back out, confirmed still working in the same test) is completely untouched, so "it needs a powerful shot" to actually eject a scored disc still holds. Fourth: "I'm not sure I like the default top-down view of the discs now...Can you show me some image samples of some discs of various colours that will allow me to choose a new basic default top-down look?" — delivered separately as a standalone comparison image (six shading styles x six disc colours, rendered on the app's actual default wood background with the same wood-grain disc texture, drop shadow and edge bevel real discs get, plus zoomed close-ups) for the user to pick from; nothing about the live disc rendering itself changes until a style is chosen. Verified with new targeted tests for the gutter-exclusion (a disc pushed past BAND_OUTER provably no longer affects the frame, confirmed identical to removing it outright) and pull-back room (the visible space below the back line, converted to board units at the frame's own scale, covers the full AIM_V2_MAX_DRAG) plus the sunk-collision radius fix, plus the complete existing regression suite (close-contact push, all three placement-overlap tests, the Round Complete flow, general Auto Zoom, the edge-zoom assist, Phase 124's own replay-speed/shadow-rotation test, and a broad smoke sweep across the V3 physics/wobble/gesture test suites) with zero behavioral changes elsewhere.) build 2026-09-15 01:41 MDT (Phase 124: five separate reports/requests in one message. First — the user pointed out a new real photo of a disc at a steep tilt looked genuinely rounded and shaded at the edge, not a flat colored ring, and asked whether the STL file could drive true 3D rendering. Rendering the ORIGINAL STL directly (matplotlib, real per-vertex lighting) matched the photo closely, proving the file's own geometry was already right — the mismatch was this app's flat 2D CSS approximation, not the model. Rather than a full 3D-engine rewrite, the user asked for the cheaper of two options: an improved CSS approximation. That render also surfaced a real bug along the way — the very first version of it looked like "one fat disc," traced to matplotlib's 3D axes not preserving equal scale across width/height/depth (the underlying mesh measured out exactly right at 1.25"x0.375", confirmed again by direct vertex bounding-box math — nothing about the actual file was ever wrong). The user then compared that corrected render side-by-side against their real photo and flagged one more difference: the real disc has a noticeably SHARPER crease where the flat face meets the rounded edge than the STL's own gradual blend. The disc's CSS (.disc/.holder-chip background) now layers a radial-gradient rim-shading pass on top of the existing, untouched, separately-approved conic-gradient — a crisp bright crease right at the flat cap's own edge (DISC_EDGE_FLAT_FRAC, 85% radius) followed by a curved darkening toward the rim — plus a matching thin inset highlight on the cap itself, so the outer ring now reads as a lit, rounded bevel instead of a flat band of solid color. Second, a bug report: "the shadow of a spinning disc should not spin" — applyDiscFrame was copying the disc's own spin rotation straight onto its separate .disc-shadow twin, so the shadow's fixed-light directional offset visibly swept around with every spin; the shadow twin now only ever counter-rotates against the board's own camera angle (matching every other shadow in the game — see syncHoleShadowRotation/syncPegShadowRotation/syncDiscShadowRotation's shared "fixed room light" idea), never the disc's own physics spin, while still picking up the same jump/wobble squash scale. Third — "the replay speeds do not seem to work... if pressed before Replay Again they will adjust the speed": traced to playHistoryReplayCurrent (which drives Replay Again/Previous/Next Shot in the history browser) hardcoding speed preset 1's percentage no matter which of the three speed buttons was actually selected, so presets 2/3 had literally zero effect there — only a direct press of a topbar speed button ever honored them. The three speed values are also renamed straight to their own percentages per the user's spec (33%/20%/10%, replacing the old 20/10/5 and their bare "1"/"2"/"3" labels), and the selected preset is now a genuine persistent choice — it stays selected after a replay finishes instead of resetting to none — so every replay path consistently uses whichever speed the player actually picked. Fourth, Auto Zoom: a real screenshot from the user's own phone showed a much tighter, more useful crop (back line, every disc, a little more board up top) than this app's Auto Zoom setting produced. The old fit-scale math enclosed everything in a CIRCLE around the board's true center and fit that circle into the SMALLER of the viewport's width/height — on a portrait phone that wastes most of the extra vertical room and centers on the wrong point entirely. It's rebuilt around the actual screen-space bounding box of the real required content (every disc plus the shooter's own back-line arc, rotated through a real DOMMatrix to match the camera's live orientation exactly), fit into the viewport's width AND height independently and panned to that content's own center — producing a frame that matches the user's reference screenshot directly. Verified with new dedicated tests for the wobble-profile shading, the shadow/spin rotation split, the persistent speed-preset selection and its use by history-replay, and the bounding-box auto-zoom math, plus the complete existing regression suite.) build 2026-09-15 00:39 MDT (Phase 123: the user didn't like the Phase 122 demo — "I don't like your profiles of the disc in 3d space. those red ones" — and supplied a grid of real photos of an actual disc being tilted up on tweezers (plus two video links, which turned out to be inaccessible to this app's fetch tooling beyond basic metadata — Google Photos share pages render their video client-side). Comparing the photos directly against the demo pinpointed the real problem: Phase 117's "cap-shrink" effect, which shrank the disc's flat painted face toward nothing as it tilted so more of a differently-shaded "rim" would show through, produced a pronounced two-tone bullseye (small bright core, wide dark ring) by 45-90° of tilt. The real photos show nothing like that — a genuine disc's edge is the exact same colour as its face, so a real tilting disc just becomes a solidly, near-uniformly coloured ellipse, with no growing dark ring at all. The tilt-driven cap-shrink is now permanently 0 (the CSS variable stays wired up for a future, subtler version, but nothing currently drives it above zero) — the disc's own scale() squash from Phase 122's corrected discWobbleHeightScale is what actually sells it standing up, right down to a thin sliver at a full 90°, and that math is untouched. Verified with an updated comparison render (side-by-side old-vs-new) plus the complete existing regression suite.) build 2026-09-15 00:25 MDT (Phase 122: the user supplied an actual 3D model of a crokinole disc (STL + OBJ) and asked two things: does it match a real disc's dimensions, and can it be used to drive the jump/spin/wobble animations? Measuring the files directly (bounding box 31.75mm x 9.525mm, exactly 1.25"x0.375") confirmed it's precisely a regulation NCA tournament-size disc, and matches the ratio the game's own physics already assumed (DISC_THICKNESS_RATIO=0.3). The real payoff turned out to be the disc's actual EDGE SHAPE, not just its ratio — after "Grok was unable to understand me," the user iterated through a few hand-drawn reference images to nail down exactly what they meant, converging on: a disc that's flat through the middle ~85% of its radius, then tapers smoothly on both faces to a knife-sharp point exactly at the true 1.25" rim, with no straight vertical wall anywhere ("no vertical flat" per the STL's own header comment) — quite different from Phase 117's assumption of a flat-sided cylinder. discWobbleHeightScale (used by both edge-wobble and hole-lip-wobble) is rebuilt around this real profile: pixel-measured off the user's reference image and fit to a quarter-ellipse taper (rmse ~0.016), then plugged into a proper closed-form solve for the disc's true silhouette height at any tilt angle, replacing the old flat-cylinder guess. Both formulas still land on exactly the same two guarantees (full diameter at rest, exactly the disc's true 0.3 thickness ratio standing straight up on edge) but the curve between them is now correct instead of approximate — the old formula actually overshot past the resting size by up to ~4% around a 15-20° tilt, which the new one no longer does. The disc's resting "flat cap" bevel inset also moved from an eyeballed 8.5% to a profile-derived 7.5%, so the flat painted face now visually ends exactly where the real disc's flat face does. Verified with a new dedicated test that cross-checks the closed-form solution against a brute-force numerical search across a full tilt sweep (agrees to within 1e-3), confirms both endpoint guarantees, confirms the curve is now monotonic and never exceeds 1.0, plus the complete existing regression suite including the three pre-existing wobble tests (updated to reflect the corrected expected values).) build 2026-09-14 22:46 MDT (Phase 121: after trying both Phase 120 mouse-mode indicators side by side, the user's verdict — "please eliminate the bottom version that was showing the buttons in the bottom corner" (on desktop mouse-sized screens) — removed the non-interactive bottom-corner button-style status display entirely, leaving only the floating "Mode: ___" text label at top-center as the sole indicator for the right-click Cancel/Reposition/Aim & Shoot cycling on mouse/non-touch devices. Purely a mouse-play UI simplification — the touch-device corner buttons, the right-click cycling logic itself, and the jump-easing fix are all unchanged. Verified with the updated Phase 120 button test suite (now checking for the label alone) plus the full existing regression suite.) build 2026-09-14 21:55 MDT (Phase 120: three requests in one message, plus a mid-turn follow-up. First (user report — "I love how the black disc in Round 2 Shot 19 gets larger as it jumps up in the air toward the camera...it seems to grow and shrink a little abruptly though"): the mid-air jump scale used to snap on and off as a flat boolean the instant a hard-hit jump started/ended. It's now driven by a smooth parabolic 0-to-1-to-0 arc (jumpHeightFrac) computed from the physics engine's own jump-progress counters and recorded every physics frame, so the disc eases up to full size and back down over the whole flight instead of popping. The user's own linked match file (a JSON export on their server) was too large for this app's fetch tooling to retrieve directly (over the ~30MB single-response limit), so the fix was verified instead with a dedicated physics-level test that forces a real hard-hit jump and confirms the recorded scale trace starts and ends near zero, peaks at full size in the middle, and never steps by more than a small fraction between consecutive frames — happy to check the exact Round 2 Shot 19 moment directly if a smaller/trimmed excerpt of that file can be provided. Second (user report — "The buttons only seem to show when I am in the aim force mode. I only need the Cancel Shot button to show then. the other buttons can be shown all the time"): the single relabeling corner button from Phase 118/119 is replaced with three independent, always-coexisting buttons — a red "Cancel Shot" (visible only while actively aiming/flicking, and not already cancelled), a gold "Reposition", and a green "Aim & Shoot" (both visible for the entire gesture, including before the first pull). Per the user's explicit ask ("On a non-touch screen these buttons should not appear. Can you detect that?"), the whole group is now gated behind a real touch-capability check (any-pointer:coarse, maxTouchPoints, ontouchstart) and never appears on mouse-only devices. Third, a mid-turn follow-up ("if people click the left mouse button...can you make it so that you can toggle between, Cancel, Reposition, and Aim & Shoot modes"), clarified after a follow-up question to mean a RIGHT mouse-button click cycling Cancel Shot -> Reposition -> Aim & Shoot -> repeat, each step applying that mode for real (cancelling the shot, arming reposition, or dropping the disc back for a fresh pull-back) so mouse play gets the same three actions without needing on-screen buttons. Since the user wanted to compare indicator styles before picking one ("can we try both and I will tell you which one to eliminate after I see them?"), BOTH a floating "Mode: ___" text label and a non-interactive button-style status strip are shown together on mouse/non-touch devices for now. Verified with new dedicated Playwright tests covering the eased jump-scale trace, all three touch-button visibility rules, complete button absence on non-touch, and the full right-click cycling sequence with both indicators, plus the complete existing regression suite (with the pre-existing Phase 118/119 corner-button tests updated to the new three-button API).) build 2026-09-14 20:42 MDT (Phase 119: three real-device bug reports against the Phase 118 Cancel Shot/Reposition corner button, all in one message. First: "if the zoom changes during the aiming, repositioning, etc. then the Cancel button needs to adapt and move to the new bottom corner...it was not visible as it was painted off screen." The button's own CSS corner offsets assumed the full layout viewport is always what's on screen, which real native browser zoom/pan can violate independently of this app's own board zoom (a CSS transform scoped to #board-wrap that the button, appended straight to , was never affected by in the first place). Fixed by having the button track window.visualViewport's actual reported visible rectangle live, with resize/scroll listeners so it repositions itself even without any pointer movement, falling back to the old static corners on browsers without that API. Second and third, reported together: "It is easier to get into reposition mode now, however...after getting into the reposition mode after starting and canceling a shot, I can't get out of reposition mode to get into the aiming/force selection mode" and "the reposition button disappears from the screen for some reason." Two real causes, both fixed. (a) The corner button was unconditionally torn down the instant reposition mode was entered, on the theory it had "nothing left to offer" there — leaving a full release as the only way back to aiming and making the button look like it had simply vanished. It now stays, repurposed as a "Back to Aim" button, so tapping it returns to aiming (re-anchored at the disc's current spot on the back line) without ever releasing the pointer. (b) The hard-press-to-reposition check used a flat pressure floor (PointerEvent.pressure >= 0.75) that real Android touchscreens — whose reported "pressure" is often derived from touch contact-ellipse size, not true force sensing — could clear just by resting an ordinary touch, especially right after tapping Cancel Shot with the same finger still down near the disc. It now also requires a genuine RISE over that gesture's own first observed pressure sample, never trips once a shot's already been cancelled via the button, and the floor itself was raised slightly (0.85) for extra headroom — a deliberate hard press still arms reposition exactly as before. Verified with four new targeted Playwright tests (the false-trigger case is gone, a genuine hard press still works, the corner button now survives reposition mode and its "Back to Aim" tap actually returns to aiming, and the button visibly repositions on a simulated visualViewport change) plus the complete existing regression suite, including an update to Phase 118's own corner-button test to match the new "button stays, offers a way back" behavior.) build 2026-09-14 19:31 MDT (Phase 118: a correction to the Phase 117 info-area fade plus six new requests, all from one message. First, the correction, flagged in strong terms: "The info area fade update you just made was implemented incorrectly...there is a large jump of the screen. This is exactly what is specifically asked you NOT to do. I want the screen to stay put and the board that was covered by the info area should fade into view with no movement of the board." Phase 117's fade still animated a real height collapse on elements that were normal in-flow flex siblings of the board, so the board kept reflowing into the freed space throughout the transition, however gradually. Fixed properly this time: topbar, the score/turn HUD, instructions, the play-by-play log, and the action panel are now wrapped in one #info-overlay div that gets lifted out of the flex layout entirely (position:absolute) during Play/Builder-Play, floating on top of a board that always renders at its one true full size — collapsing now only ever animates this wrapper's own opacity, never anything the board's own layout could react to. Verified with a dedicated geometry test asserting the board's center/scale are bit-for-bit identical whether the info area is expanded, collapsed, or mid-transition, on both mobile and desktop widths. Second: "In cell phone mode...after the disc is positioned and you begin to drag back to initiate the aim/power meter, I want to allow another hand's finger to be used to shoot...one hand's finger holds down and stays put...another finger...can be used to adjust the power and aim...when the initial finger is released...the shot occurs" — a Soccer-Stars-style two-finger aim, now supported: a second, independent touch can take over aiming entirely while the original finger just holds, and only that original finger's release ever fires the shot (the second finger's own release simply freezes the aim where it was left). Third, two reposition improvements: a strong press directly on the shooting disc mid-aim (via PointerEvent.pressure, so only real force-sensitive touchscreens ever trigger it) now arms repositioning immediately, same as the existing hold-still gesture; and a new on-board "Cancel Shot" button now floats in whichever bottom screen corner is farthest from the aiming finger for the whole time a Pull & Release aim is active, hopping to the opposite corner as that finger moves — a second finger tapping it freezes the aim (so releasing won't fire) and swaps the same button to "Reposition", tapping which arms reposition mode (the disc's existing gold glow) and removes the button. Fourth: Flick shooting style skips the Cancel Shot state entirely per the user's spec, showing only the Reposition button once a flick is underway. Fifth: removed the "Shot Settings" band (the Power meter + Reposition button) that used to render in the action panel — fully superseded by the new corner button, per "it is not needed there at all." Sixth: the collapsed-state toggle (the single arrow in a circle, top-center) had its backdrop lightened and its shadow softened so it reads as a true floating button rather than sitting on a solid band, with the rest of the top of the screen now showing the board directly through the new overlay architecture above. Seventh, a new "Auto Zoom" game setting (off by default): when enabled, the camera automatically re-frames itself at the start of every single shot to a scale that fits every disc currently on the board (each with a half-disc buffer) plus the shooting player's own full back line, recentering the pan to do it. Verified via targeted Playwright tests for each of these seven changes (the board-never-moves geometry check; hard-press-to-reposition; the full Cancel Shot → Reposition → armed-glow button sequence; the Flick-mode button variant; the two-finger aim hand-off, freeze-on-second-release, and fire-only-on-first-release behaviors; and Auto Zoom actually engaging on the very first shot and staying inert once turned back off) plus the complete existing regression suite (Phase 112's fixes and a 60-shot AI match, capture-still-works, Phase 113's V3 behaviors, Phase 114's seat-sync and Doubles drag tests, the reposition debounce, the Round Complete modal, and the info-area auto-fade cycle) with zero behavioral changes elsewhere.) build 2026-09-14 17:56 MDT (Phase 117: six requests from one message, three reference photos of a real disc and a stacked set included. (1) "when you show wobble, the 2D representation of the disc needs to imitate depth...An NCA official tournament disc is 1 and 1/4" diameter × 3/8" thick...so when a disc wobbles this 3/8" width needs to be represented accurately." The old wobble squash was an arbitrary flat linear factor with no relationship to a real disc's own proportions. Replaced it with the actual top-down orthographic projection of a genuine short cylinder tilting up (cos(tilt) + 0.3×sin(tilt), where 0.3 is a real NCA disc's own thickness-to-diameter ratio) — a disc fully up on its edge now settles at exactly its own true 0.3 ratio instead of collapsing toward a physically-impossible flat line, and the flat painted "cap" (the existing bevel-rim disc styling) shrinks as it tilts so more of the disc's own real barrel/edge shows through, matching the reference photos. (2) "sometimes I go to make my shot and my shooting disc is too close to the edge of the screen so my finger is not able to be pulled back far enough...the board display should...try and keep the zoom level at the same setting and only adjust it if necessary...only adjust enough to allow the shot to be taken with the current amount of power applied." Found the app already had a mature, well-built "edge-zoom assist" doing exactly this (easing zoom out only while the pull gesture is pinned near the visible edge, capped so it never zooms out further than fitting the whole board, reversible as power eases back off) — one real gap against the new wording: it kept easing toward that whole-board floor for as long as the finger stayed near the edge, even after 100% power was already reachable. Now it stops easing out the moment full power is achievable, never zooming out further than that shot actually needs. (3) "it still needs to be much easier to reposition the disc...hover his finger over the shooting disc for a second or so, and have the reposition glow effect kick in...Please make the solid glow ring thicker on mobile" plus "if a player...is trying to apply power for the first time after pulling don't reset to reposition mode too easily. They have to extend the power level out a little ways first." The hover-to-arm-reposition gesture already existed but had no debounce — even the very first tiny jitter of a fresh pull, before any real aim was ever established, could trip the same hold-timer as a deliberate "changed my mind" return. It's now gated on the gesture's own peak pull force reaching a small deliberate threshold first, so a shot that never really got going just lets the pull continue instead of priming reposition. The touch-only solid ring (already thickened once before, Task #98) is thickened further (6px to 10px) per the direct report that a fat fingertip still made it hard to tell reposition mode was active. (4) "when a round is over, don't just jump immediately into the next round. Show a popup that says 'Round Complete' and has the points for each player shown. Prompt to start next round." This pause-and-prompt modal already existed for 4-player Match Mode specifically; every other (100/200/300/400/500) game skipped straight past the round result into the next round's setup. Extended the exact same modal (and the exact same "Start Next Round" button that actually advances the round) to every game, scored against each player's real round points and running total toward the target score instead of match points. (5) "the information area at the top of the screen...[should] automatically disappear once a disc is dropped and is ready for aiming...after the shot is fully over it can be shown again...gradually fade in and out but don't take too long...do not adjust the board positioning in any way...without any flickers, or studders." The existing manual show/hide toggle for this area used a flat display:none — instant, and giving the browser nothing to animate through, so the board's own reflow into the freed space happened in the same single snap as the content vanishing. Replaced that with a matched opacity+height fade (about a quarter second) so both halves — the content fading out, and the board smoothly growing into the space it leaves — happen on one continuous timeline instead of a jump; wired to a new automatic hide-while-aiming/restore-after-the-shot cycle (any device, not just phones) that's careful never to fight a player's own manual choice to keep it hidden. Caught and fixed one real regression along the way: an early version of that same CSS change nudged the whole game screen's layout by a fraction of a pixel even at rest, which would have very slightly thrown off the on-screen aim/reposition geometry — traced via a dedicated geometry test and fixed by scoping overflow:hidden to only the actively-collapsing state. Verified via targeted tests for each of the five changes (disc-wobble math against the exact expected trig values, the zoom-assist's stop-at-100%-power behavior, the reposition debounce's gate in both directions, a full simulated round through the new popup and Start Next Round button, and the auto-fade cycle correctly leaving a player's own manual collapse alone) plus the complete existing regression suite (Phase 112's fixes, a 60-shot AI match, capture-still-works, Phase 113's V3 behaviors, Phase 114's seat-sync drag tests, and Phase 116's near-miss visual-gap rendering) with zero behavioral changes elsewhere.) build 2026-09-14 16:28 MDT (Phase 116: another real exported match, Round 1 Shot 23 — "on the screen it appears as if the red shooting disc contacted, every so little, but contacted the other red disc in the 15 zone. Both of these red discs should have come off the board as no other players disc was contacted." Traced the actual physics of that exact shot: the two discs' closest approach was 10.62 units center-to-center against 10.42 needed to genuinely touch — a real, if razor-thin (about 0.02"), miss. Since an opponent disc was on the board and the shooter touched nothing, the game's existing "no-contact" foul rule had already correctly fired and ditched the shooter — that part was working exactly as designed, not a bug, so the underlying touch calculation is completely untouched here. What actually needed fixing was that the board can't visually show a gap that thin, so a clean miss reads as contact on screen. Discs now get a tiny (2px, capped at a fraction of a disc's own radius) rendering-only nudge apart whenever they're genuinely NOT touching but close enough that the true gap would otherwise round away to nothing — scoped to only the two places a shot's outcome is actually watched (the live Play Crokinole board, and the same board once a Slo-mo Replay/History Browse animation finishes), and only ever for discs truly at rest, never mid-flight (resizing while discs are still moving would read as flicker). A disc that's genuinely resting touching another — which real Crokinole play produces constantly, on purpose — is left completely alone at full size; only a real, honest-to-goodness non-touch ever gets nudged. Setup Mode and Scenario/Skills-Builder editing are entirely untouched, since packing discs in deliberately tight there (to lay out a practice position) has to keep working exactly as before. Second, from the same message: "when a player is setting up their shooting disc, they are not allowed to overlap, or touch another disc." Found a real bug in the placement overlap-avoidance search: pushing a freshly-placed disc clear of one sitting right at (or very near) the ±45° corner where a seat's own back-line touching zone ends could fight against the very next step that re-clamps the disc back onto the line — the two pulled in different enough directions that the result stayed overlapping the other disc by as much as half its own width, converged there and never recovered. This is exactly the scenario that made the new close-contact push shot (Phase 115) look reachable by simply overlapping outright rather than only ever getting very close — a disc dropped anywhere near that same corner never actually got pushed clear. Added a proper fallback search of the whole legal "touching the line" region (the exact same one isOnBackLine already grants, corner lean-in included) for the closest clear spot whenever the original push-then-reclamp result is still found overlapping — placements everywhere else were already resolving correctly and are unaffected. Verified with dedicated tests at dead-center, near-corner, and exactly-at-corner placements (all now reach the full required separation), a rendering-only check confirming near-miss discs get nudged apart on screen while genuinely-touching ones and Setup/Scenario discs stay full size, plus the complete existing regression suite (Phase 112's fixes, a 60-shot AI match, capture-still-works, Phase 113's V3 behaviors, and Phase 114's seat-sync drag tests) with zero behavioral changes elsewhere.) build 2026-09-14 15:52 MDT (Phase 115: two real-match reports. First, from an exported match: "when a player places a disc on the shooting line and very close to another disc already on the board... a shot can be made that would cause both discs... to both slide in the direction that was aimed... [used] to send 2 discs of the same colour into the center 15 point zone... the more force that is used the stronger both discs can slide forward together" — a specific "Round 2, Shot 7" example was given where two same-colour discs sitting almost touching should have both driven toward center on a firm hit. The existing "push-through" mechanics all gate on impact speed as a fraction of the engine's own MAX_SHOT_SPEED, which is deliberately calibrated for extreme trick shots roughly 9x a real board's diameter — so a genuinely firm, realistic "fairly strong" shot (even one 2x the board's own diameter in unobstructed reach) could never come close to tripping them. Added a new, separate "close-contact push shot" detector that instead asks the geometric question directly — has the striker travelled only a hair since it was launched this shot before it hits a disc sitting essentially still, dead-on? — and, only then, blends in a much lower, speed-ramped restitution so the struck disc surges away while the striker follows close behind, exactly as described, tapering out completely for soft taps, distant hits, or anything glancing enough to risk being an intentional double/carom shot instead (kept a clean margin above that shot's own established angle band so the two mechanics can never collide). Six new tunables under a "Close-contact push shot" group in the Physics Playground. Second — and this turned out to be the bigger one — two more reports ("Round 2 Shot 16... travelling too fast for it to simply fall in... should have travelled past the 20 hole with a good bend to the right... a small wobble too" and, more generally, "I cannot seem to get a situation where a disc is struck... too fast to sink nicely but not fast enough to coast over the hole... jump back... extreme wobble... flip and land... even in the 20 hole again... contact the back edge... wobble/jump off the table") both traced back to the same discovery: the app's actual default hole-capture model this whole time has been "V2" (Task #235's original staged near-miss ladder), and below its lowest tier every fast-arriving disc gets an unconditional, speed-blind "guaranteed capture" with no bend, wobble, or sail-over possible at all — which is exactly the flat, deterministic behavior both reports describe. Phase 111's "V3" model (a continuous, from-scratch rebuild covering Drop/Wobble/Deflect-and-Hook/Flip/Jump across the full speed×coverage range, research-backed and already fully built and tuned in Phase 112-113) was sitting right there behind a Settings toggle nobody had turned on. Rather than re-patch V2's discrete ladder, V3 is now the default for everyone; re-running the exact reported shot (264 units/s arriving 5 units from center) through the new default 400 times over produced sinks only ~26% of the time, with the rest split between wobble/deflect-with-bend sending the disc anywhere from just past the hole to clear across the board, and the occasional jump — vs. V2's 100%, no-exceptions capture for that same shot. V2 itself is untouched and still one click away for anyone who preferred its feel. Verified via targeted physics-engine trials (both new mechanics) plus the full existing regression suite (Phase 112's fixes, a 60-shot AI match, capture-still-works, Phase 113's V3 behaviors, and Phase 114's seat-sync drag tests) with zero behavioral changes elsewhere.) build 2026-09-14 15:03 MDT (Phase 114: the last remaining piece of the "GAME ANALYSIS ISSUES" report's seat-orientation request — the Setup screen's own Seats card. Previously the Players list and the board preview's seat placement were only loosely connected: dragging a player row to reorder the list was purely cosmetic (it never touched who sat where), and dragging a colour chip to a different board seat never touched the list order either — the two could drift out of sync with each other with no way back short of starting over. They're now kept as two views of the exact same ordering, synced from either side: drag a row's handle to reorder the Players list and the board immediately re-seats everyone to match, in that new order; drag a chip on the board to place or swap seats and the Players list reorders itself to mirror the new seating (walked in ascending seat order) — drag either one and the other one follows. The board preview also now visually "rotates" so whoever's first in the list always shows at the bottom of the diagram, exactly matching the same human-sits-at-the-bottom convention already used everywhere else in the app (the runtime board-rotation work from Phase 113), so reordering the list also reorders who appears at the bottom/left/top/right of the preview, live. Only the setup-preview's visual placement changes here — the real physical seat geometry used everywhere else in actual gameplay (seatAngleDeg/the 4 real board corners) is untouched. A player dragged off the diagram to unseat them drops to the end of the list rather than keeping their old spot, since an unseated player has no seat left to mirror. Works the same way for every player count (1-4) and for Doubles' own fixed opposite-seat team pairing, which is unaffected. Verified with both direct state-invariant tests and genuine simulated pointer-drag tests (real mouse-down/move/up through the actual drag-handle and drag-chip DOM elements, not just calling the underlying functions directly) for: list-reorder-→-board-follows, board-swap-→-list-follows, unseating, 2-player's opposite-corner canonical seating, and Doubles — plus the full existing regression suite (Phase 112's three physics fixes, a 60-shot AI match, and Phase 113's Slo-Mo/zoom/rotation/V3-physics tests) to confirm no regressions. This closes out every item from the original physics/UX report.) build 2026-09-14 14:48 MDT (Phase 113: continuing straight through the rest of the same "GAME ANALYSIS ISSUES" report Phase 112 didn't get to yet. Slo-Mo: measured real wall-clock replay durations at all three speed presets before touching anything and confirmed the existing 1/2/3 speed mechanism was already scaling correctly — "the speeds aren't working" was a perception issue, not a bug, because the base speed itself was simply too fast to read as slow motion; lowered the base Slo-Mo Replay speed from ~50% to 20% of real time so all three levels are now genuinely slower. Slo-Mo Replay and shot-history browsing now always force the board to the human player's own bottom-quadrant viewing angle for the duration of the replay (restoring whatever the live rotation was the moment you exit), per "the slo-mo replay would only be used by a human who shoots from the bottom quadrant — please show replays from that perspective only." Auto-zoom: an AI's turn now automatically zooms the board back out to full view the moment it starts, and restores your exact previous zoom level and pan position the moment it's a human's turn again, so a phone player zoomed in for their own precise shot no longer has to manually zoom out to see what an AI's shot actually did. Board orientation (gameplay half only — see below for what's still open): in the main "Play Crokinole" match mode, a single-human game now keeps the board permanently rotated to that human's own seat the entire match, exactly "as if sitting opposite" every AI regardless of whose turn it is; a multi-human game rotates to each human's own bottom-seat view on their turn and simply leaves the board as it was for any AI turn in between two humans. Verified with targeted tests for both the fixed single-human case and the per-turn multi-human case, plus the zoom save/restore behavior, plus a full 60-shot AI-match regression and the three Phase 112 physics-fix tests (all still pass — no regressions). General V3 Physics additions (three new behaviors, all opt-in via the Physics V3 experimental model, with 12 new Playground tunables): (1) "A disc dropping into the 20 that was almost going to sail by should wobble as it drops in" — a Drop outcome rolled at high remaining power (a real near-miss that happened to drop anyway) now always takes the visible slide-in animation with a boosted jiggle, instead of silently vanishing the instant coverage/distance alone would otherwise have allowed an instant sink. (2) "Hit a little too hard should have a greater chance of briefly falling in and then jumping back out — straight back at the shooter on a very straight shot, or on a warped angle otherwise — with a good chance of wobbling too" — a Deflect/Jump outcome rolled inside a new "moderately too hard" power band now has a chance to upgrade into a genuine dip-into-the-hole-and-eject, reusing the existing lip-out state machine rather than duplicating it; how far the shot's heading was off dead-center controls how far the ejection angle warps away from straight-back, comet-style, and the eject can separately pick up a wobble on its way out. (3) "Discs near the hole that are just missing should bend more than currently observed" — added a Deflect bend-strength multiplier that scales the whole near-miss heading bend (both the base hole-ward pull and the random sideways hook) on top of everything already governing it. All three verified with targeted physics-only tests against known geometry (forced near-miss-drop wobble confirmed boosted, deflect bend angle confirmed to scale up with the tunable — 29.5° at 1.0x vs 73.9° at 2.5x in one measured trial — and a forced catch-and-eject confirmed to produce the expected lip-out-plus-wobble state). Still open from the same report, NOT done in this phase: the setup screen's own seat list / board-preview drag-to-reorder UI (rotating the preview so players show at top/right/bottom/left by list order, kept in sync whether you drag the list or the board) — that's the remaining half of the seat-orientation request and needs its own pass.) build 2026-09-14 19:40 MDT (Phase 112: three concrete physics bugs, root-caused against the user's own exported match file and screenshots rather than guessed at. (1) "A shot into the 20 barely contacted a white disc extended over the hole, but it barely moved given how hard I shot." Traced to shot 5 in the user's export: the shooter disc was already deep into its slow “guaranteed capture” roll-in (holeSlideFrames), which drives its position by direct interpolation with its real velocity deliberately left at zero the instant the roll began — it's still genuinely closing real distance every step, just not via velocity integration. Grazing another disc during that window computed the impact from that zeroed velocity, so the struck disc got essentially no impulse no matter how fast the original shot was. resolveInterruptedSink now reconstructs the roll-in disc's real instantaneous velocity from the same interpolation the roll-in animation itself uses, purely for that one collision's math, so a graze during this window now transfers a real, physically grounded push. (2) "A green disc bumped a red disc at fairly slow speed near the hole... the wobble animation was displayed for quite a while. Low speed alone should not cause wobble." Traced to shot 26: a near-miss inside the slow-shot tier set a full-length wobble purely from hole coverage, with no regard for how little speed the disc actually had left — confirmed against the real replay data, which showed the wobble first triggering at barely any remaining speed, then (see next item) re-triggering itself over and over for the rest of the shot. Wobble duration in this tier now also scales with the shot's own remaining speed (new Playground tunable: Slow-shot near-miss min wobble), so a nearly-stopped near-miss gets little to no dramatic wobble instead of the full-length animation every time. (3) "Before it contacted any peg or other disc, the green disc near the twenty dropped in the hole... we should at least require some sort of force on the board to initiate that effect." Root cause, confirmed directly from the exported shot-26 frame data: a disc that had come to a genuine, complete stop kept being re-asked “do you want to fall in now?” on every remaining physics tick of that shot (and would have kept being asked on every tick of every LATER shot's own simulation too, since hole-capture is checked across every body on the board each step regardless of whose turn it is) — the replay showed this one disc's wobble state fully resetting and re-rolling well over a dozen times back-to-back while sitting dead still. A disc at a genuine standstill (speed exactly zero) is now left alone entirely until something real disturbs it — struck by another disc/peg, or knocked loose by a sunk-disc/interrupted-sink collision — matching the user's own "require some force" request; a disc still coasting, even slowly, is completely unaffected and keeps its normal chances every tick right up until it actually stops. All three fixes verified directly against synthetic replays of the reported geometry (a grazed roll-in disc now picks up a real, proportionate push instead of none; a near-stationary near-miss now gets little to no wobble instead of the old flat duration; a disc parked at rest never resolves on its own across 3000+ idle ticks) plus a 30/30 sanity check that ordinary dead-center slow captures still work exactly as before, and a 60-shot full AI match with zero errors. Still open from the same report, not yet started: default Slo-Mo Replay speed/verifying levels 1-3, always replaying from the human's bottom-quadrant perspective, auto-zoom-out during AI turns, the full seat-order ↔ board-orientation rotation system, and the three new general Physics V3 behaviors (wobble-on-a-near-miss-that-still-drops, a too-hard hit briefly catching then ejecting, and stronger near-miss bend) — next up.) build 2026-09-12 22:05 MDT (Phase 111: "I still what you to work on another problem. I wish you to save the current physics model... and then work on a new physics model... allow me to toggle between Version 2 (current version) and the new Model 3." The user also asked their own Grok AI a detailed question about the power/deflection/wobble/hook/flip/jump behavior a disc shows crossing the center hole, asked me to answer the same question independently, compare the two answers, and design the best model I could from the comparison (research delivered separately as crokinole-physics-v3-research.md — sourced real disc/hole dimensions, the official National Crokinole Association scoring rules, and a from-scratch physics writeup, since actually watching the requested game footage frame-by-frame isn't something this assistant can do). A new "Physics Model" setting (V2/V3) now sits in Game Settings, defaulting to V2 — the existing Task #235 staged near-miss model, completely unchanged and untouched by any of this. V3 is a genuinely different hole-capture model built on two continuous axes instead of a discrete stage ladder: remaining shot power (as a fraction of its own clean-sail-over edge) and how much of the disc actually covers the hole — the same "Power Level inches" and coverage-fraction quantities this engine already computed internally, now driving five possible outcomes (Drop, Wobble/Leaner, Deflect/Hook, the rare edge-Flip, and Jump) blended continuously across that whole surface from 12 named, independently-tunable calibration points, rather than jumping between fixed stages. The Leaner rule needed no new code at all once implemented correctly — the NCA's own "not lying flat means it's a 15, not a 20" rule just falls straight out of this game's existing ring-distance scoring, since the hole already sits inside the 15-line. V3 deliberately reuses V2's own already-tuned "how it looks/feels" building blocks (bend angle, wobble timing, jump timing, and the same rare "flips onto its edge and spins like a coin" mechanic a hard disc-disc hit can already trigger) rather than duplicating them — it only owns the decision of which outcome happens, not how each one is rendered. Verified directly: with V3 selected, a slow shot aimed dead-center drops the large majority of the time, the same shot aimed a few degrees off drops far less often and genuinely deflects instead, a shot near V3's own sail-over edge aimed dead-center shows real variety (drops, wobbles, and jumps all occurring), and a full AI-vs-AI match runs error-free under the new model — all while every existing V2 regression check stays exactly as it was, since V2's own code path is completely unchanged and remains the default.) build 2026-09-12 19:10 MDT (Phase 110: three follow-up reports after actually seeing Phase 109 in play, plus a photo of real discs. (1) "That little tick mark is dumb, remove it. Crokinole discs don't have that so we can't have it either." The Phase 109 spin tick-mark is gone — CSS rule, child element, and creation code all removed outright, not just hidden. (2) "Our discs are perfect in texture but in real life they have little imperfections and you can see a little bit of the wood grain through the paint... hopefully you will be able to see the disc spin a little with this addition." Every disc (on the board, in the tray, and resting in a 20's/-10's holder) now gets a small pre-baked, semi-transparent grain-and-fleck texture laid over its own colour with mix-blend-mode so the colour still reads clearly — six variants, picked and rotated per disc from a stable hash of its own id so it does not reshuffle on every re-render. Because it is an ordinary child riding inside the same element the disc's own rotation already animates, the grain sweeps around for free as the disc spins, same as the removed tick-mark did, just built out of a believable imperfection instead of an invented mark. (3) "A shot near the hole still goes in way too easily. it almost snaps into the hole when you get close... in the places when a subtle deflection would occur... currently has the disc snapping into the hole." Found the real bug: the slow-shot "guaranteed capture" tier below the near-miss staged system only ever checked SPEED, never checked how much of the disc actually covered the hole — any slow-arriving disc that crossed just barely past 50% coverage dropped in every single time, with no bend or wobble at all, which is exactly what read as a magnetic "snap." That tier now checks coverage too: only a well-centered slow shot still drops for certain; anything more marginal gets a coverage-scaled chance instead, and on a miss now visibly bends toward the hole and wobbles/skims past it rather than silently sailing on or snapping in. Verified directly: a dead-center slow shot still sinks reliably (20/20 in testing) while the same force aimed a few degrees off the hole's center now sinks far less often, genuinely deflecting instead — with the existing near-miss staged system (faster shots) and every AI-reliability regression check both unaffected.) build 2026-09-12 16:45 MDT (Phase 109: eight issues from one batch of reports. (1) "When the disc is spinning I wish to see it on the game board... devise a way to indicate spin on the disc." Added a small radial spin-marker mark to every real board disc, riding above the disc's existing flat bevel cap (a z-index trick matching the same layering already used for stack riders/badges) so a disc's rotation is now genuinely visible as it turns, not just implied by physics numbers under the hood. (2) "When the disc is wobbling I wish to see it on the game board... a beter way to indicate wobble... It should be easily recogonisable as cleary a wobble." The far more common near-miss hole-lip wobble (as opposed to the rare coin-flip edge wobble, which already had its own squash effect) previously had no visual treatment at all beyond an internal position jiggle; it now gets its own elliptical squash-and-recover animation plus an amber-tinted glow, purely cosmetic and kept mutually exclusive with edge-wobble so the two remain visually distinct. (3) "I wish to remove some settings... I don't need an Aim and Power UI choice any more. Just use V2. I don't need Power Input Classic or Two-tier any more." Removed both the UI Version picker and the Power Input Classic/Two-Tier picker from Settings entirely — the app is now permanently on the V2 aim-and-power system — and deleted the now-dead V1 rendering code and the Two-Tier power-curve subsystem behind them (roughly 90+ lines removed), while keeping the one still-legitimate use of the older "Classic" force curve (the separate Scoring Scenario Action Mode drag gesture, unrelated to UI Version). (4) Cleaned up the settings left orphaned by that removal, including a fully dead Physics Playground tunable that only existed to size the old V1 aim arrow. (5) "Examine the remaining settings... clean them up, combine settings where necessary and remove unnecessary ones... improve the descriptions." Merged the separate Shot Trail Style card into the main Shot Trails card (matching the existing Wax/Salt Texture card's combined pattern) and fixed two settings whose hints were unclear or outright wrong (a mislabeled "Dot Amount" control, and a "Dot Length" hint that described the wrong reference size). (6) "When rotating the board between players shooting can you make it rotate smoother, it seems clunky." Found the root cause — the disc's separate drop-shadow layer was snapping instantly into its rotated position while the disc itself eased smoothly, a visible desync on every rotation — and gave the shadow layer the same transition as the disc it belongs to. (7) "when a disc goes partially over a hole bending/deflection should be occurring way more than I am seeing." Raised the gravitational-bend curve's maximum lean angle from 34° to 50°, so grazing near-miss shots visibly bend/deflect much more than before. (8) "Discs of a medium speed that go mostly toward the hole are getting sunk far too easily... they should be deflecting or wobbling a lot more." Softened the three "catch anyway" capture-chance stages of the near-miss system (roughly 0.85/0.5/0.2 down to 0.72/0.38/0.14) so shots that graze the hole at medium coast distance now genuinely miss/wobble/deflect more often, while the fully deterministic "dead-center, no argument" capture tier underneath the staged system — and a clean high-force sail-over — are both untouched and confirmed still fully reliable.) build 2026-09-11 17:36 MDT (Phase 108: two requests in one message. First: "add a setting for Show Power Level [yes|no]. If it is set to show I would like you to display the number matching the power level as a user adjusts it on the board... just to the left or right of the shooting disc so that it is visible on the board depending on which side players shooting line the shot is taken from. the smallest shot will be 0.25 (or 0.25")." Added a Show Power Level setting (off by default) in Game Settings; when on, the live real-inches distance the current pull/flick would actually send the disc is drawn right on the board next to it as it's adjusted, offset to whichever side of the firing line stays clearest of both the aim arrow and the nearer screen edge, and counter-rotated so it always reads upright no matter which seat is shooting. The physics engine's own softest-possible-shot floor was lowered from a half inch to a genuine quarter inch to match. Second: "A disc shot with a force/speed power that would go 26" and touch the backboard on the other side of the board would not be able to make it over the center hole without a wobble. The wobble would cause some deflection and randomness but the disc would likely sail through. Adjust your settings to match that as the defaults. I would like to call this power level 26. Likewise, a shot with power level 4 would travel 4"." "Power Level" is now this build's own name for a shot's real-world unobstructed travel distance in inches (the same "how far would this coast if nothing were in the way" quantity the hole-capture logic already computes internally, just read out in inches) — and the wobble band's outer edge (last reworked in Phase 107's hole-lean physics) is now pinned to exactly Power Level 26" instead of its old, shorter reach, so a dead-center Power-Level-26 shot lands right at the top of the staged wobble zone: it generally still gets through, but only after visibly wobbling/deflecting first, never a silent clean pass the way anything stronger than that still is.) build 2026-09-10 17:30 MDT (Phase 107: fourteen items from one batch of reports. (1) Fixed close-range collisions where the striking disc traveled noticeably less far than the disc it struck. (2) Fixed Slo-Mo Replay so all of its speed options actually take effect, not just one. (3) Reshaped the 20's/-10's holder tube into a proper oval to match the reference image, instead of a flat-sided capsule. (4) Enlarged the Physics Playground's gold section subheadings and their spacing for readability. (5) Made Reposition mode easier to trigger on a hover-return, with a prominent yellow ring cue. (6) Expanded AI difficulty from three tiers (Easy/Medium/Hard) to five (Beginner/Easy/Medium/Strong/Hard), each with its own targets/forces/opponent-weighting/jitter/miss-chance profile, fully wired into setup, save/load persistence, and the AI Difficulty tuning table. (7) Made the AI aware of Forced Gambit's opening-shot restrictions: its candidate-shot search now headlessly checks whether a shot-0 direct (unbanked) 20 or a shot-1 clearing of the opponent's only disc would foul the round, and steers its search away from those lines before ever attempting them — a small residual violation rate remains under real play, the same kind of physics-randomness tolerance already accepted elsewhere in this build for the AI's deliberate-miss safety net. (8) Stopped a mobile flick gesture mid-shot from triggering the browser's edge-swipe back-navigation and closing the game. (9) Stopped the AI from throwing away its own discs for nothing: a candidate shot that costs the AI a disc without any matching gain (no opponent disc actually removed, no real safety achieved) is now heavily penalized, while genuine costly takeouts are not; Medium-and-up difficulties also now take the same kind of calculated risk with an exposed disc of their own that the old "protecting a match win" logic already used, instead of only ever playing scared. (10) Boosted wax grain color/brightness for visibility, with its own setting. (11) Reworked the hole-capture wobble band: instead of a single wobble-or-not roll, a shot landing in the band between "obviously drops" and "obviously sails past" now runs through nine progressive stages as its remaining coast distance and hole coverage shrink — a fading chance of still just dropping in, a fading hole-directed lean, growing random rim-hit kicks and wobble, and, right at the edge of a near-perfect shot, one of four distinct near-miss outcomes including a genuine caught-the-lip-and-bounced-back-out reversal; ordinary disc-disc edge wobble is also noticeably more common now; twelve new tunables were added to the Physics Playground so all of it is user-adjustable. (12) Added mobile haptic/vibration feedback for key shot and scoring moments, with its own settings toggle. (13) Doubles matches now track one shared cumulative score per team instead of per seat. (14) The AI in Doubles now correctly treats its teammate's discs as its own when planning a shot, instead of as a threat to clear.) build 2026-09-10 03:50 MDT (Phase 106: ten items from one message following a zoomed reference image of a 20's/-10's holder. First: "The on board salt needs to be even more subtler... less white/grey and more light yellow. For the gutter salt, there should be more in front of each player in a clump of sorts. the Salt can move a little during the game if a disc goes over a grain... and the salt in the gutter can modify a bit after each players shot." Board grains are now single-pixel-scale (0.09-0.18 board units) and a clear light yellow (#f2d94f) instead of the old white/grey dust; each player's own gutter salt is now generated as a genuinely tight clump directly behind their tray rather than scattered around the whole ring — which surfaced and fixed a real, pre-existing bug in the clump-spread math (TRAY_ARC_HALF is stored in degrees but was being added straight into a radian angle with no conversion, scattering the "clump" across nearly the whole gutter ring instead of a tight cluster). A disc now nudges any board grain it passes directly over a small amount, and roughly 15% of a seat's gutter grains resettle after that seat's own shot. Second: "Don't play the waxing sound if a computer is actively taking a shot... reserve the waxing shot sound to only human shots." The tray-place/wax sound is now gated on the shooting player's own type — only a human tray-drop plays it; every AI disc placement (Play Crokinole's aiTakeShot, which places its own disc directly rather than dragging from a tray) stays silent there, exactly as asked. Third, the largest item: "When a player is shooting a disc from their backline into another disc that is very close to the shooting line... with a lot of power, it should be possible to send both discs forward... almost like a super top spin. currently the shooting disc contacts the other disc and simply stops dead." Traced to the existing follow-through topspin-carry gate (task #131/#64): outside the solo-target "Drive Thru" endgame case, its minimum-impact-speed threshold defaults to 100% of max shot speed — literally unreachable — so on any ordinary board with other discs still in play, a hard square hit left the striker with only its bare post-collision residual, which is naturally almost nothing. A third, narrower gate was added rather than loosening that one (which was deliberately tight to keep real angled "double"/carom shots, at their own ~0.88-0.92 straightness, from picking up unwanted extra carry): only a hit clearly straighter than any real double (0.95+) AND already carrying most of its launch speed unlocks a strong follow-through carry, regardless of how many other discs remain on the board — "close to the shooting line" isn't tracked as a literal distance, it falls out for free, since only a shot that hasn't yet bled speed to friction can ever reach that impact-speed floor. Verified both that a close/hard/straight hit now carries the striker several disc-lengths forward instead of stopping dead, and that the same angled-double scenario (even at full power) is completely unaffected. Fourth: "Maybe have a level of dot tracks that I can change too... fade rate, dot amount, and dot length." Three new sliders (Settings → Shot Trails) now control the motion-trail dots' fade duration, minimum spacing, and size directly, replacing the old fixed constants, with a Reset to Defaults button and full persistence. Fifth: "if I indicate that there are more than one disc... the number of slots in the disc tray should match that number." A real bug in Skills Competition/solo Practice Game play: the tray wedge's slot count read game.discsPerPlayer, which builderPlayBeginCompetition/builderTestRound always hardcoded to 1 regardless of a round's own configured discsPerRound — every seat's tray showed a single slot no matter how many shots a round actually granted. It's now set per-turn from the CURRENT round's own discsPerRound (rounds within one competition can each configure a different value), with the shooter's own seat additionally showing, as filled slots, how many of their shots are still left to take this round. Sixth: "I need the disc stacking environment and display routines available in the 'Play Crokinole' game, and Skills Competition, and Practice Games... the stacking and jumping physics engine must operate consistently across all those sections." Investigated directly rather than assumed: stepPhysicsV2's stack-collapse/tumble physics and renderDiscsDOM's stack badge/rider visuals never once check which mode (game.play vs. game.builderPlay) is active — both read purely off a disc's own stackChain field — confirmed empirically by firing the identical stacked-disc collision once inside a real Play Crokinole match and once inside a Skills-Competition-style session (with all other randomness pinned) and getting bit-for-bit identical physics and visuals both times. The one real gap is authoring: Play Crokinole has no round/obstacle-editor step to pre-place a stack before a match starts, unlike Skills Competition/Practice Games' own Round Editor — matching how a real Crokinole match actually starts (empty board), so that's left as a deliberate difference rather than an inconsistency to paper over. Seventh: "when you play the wobble sounds, it would be nice if the shape of the disc that is wobbling would look like a wobbling disc... it would not be a true circle." A disc riding the existing edge-wobble physics (flipped up onto its edge, spinning like a dropped coin) is now visually squashed into a short ellipse whose long axis spins right along with the disc's own rotation, growing and shrinking exactly in step with the same physics curve that already drives its position jitter — settling back to a perfect circle the instant the wobble itself ends. Eighth: "I need another adjustment for the 20's and -10 holders. Please make it hold 10 discs... the discs are stacking vertically" (with the zoomed reference image showing wide rounded pills, not circles). The holder chips are now wide rounded pills rather than small circles, stacked edge-to-edge in the vertical tube — reads as a real column of discs seen edge-on, matching the reference image, while still holding a full 10 without scrolling. Ninth: "I also need to be able to export Practice Games and Drills." The Export button (already used for Skills Competition rounds/competitions) was previously force-hidden for any Practice Game — it's now shown there too (labeled "Export Practice Game"), on both the Practice home screen's own card and inside its editor, and a matching import-side fix routes an imported practice-game file back into the Practice Games library instead of the Skills Competition round library it would have silently landed in before.) build 2026-09-09 01:22 MDT (Phase 101: "again, there are no sounds any more. when a disc hits another there should be loud click sounds... also there is no sound for a disc sinking in a hole. and there is no sound for a disc hitting the backboard... not only that you screwed up aiming too." Two separate things here. First, the aiming report: exhaustively verified against the pre-sound-update build with a controlled, repeatable test — the exact math that turns an aimed angle into the disc's actual launch direction was checked across many angles and comes out at 0.00 degrees of error every time, and the entire physics engine was diffed line-for-line against the last build before any sound work started, which confirms nothing in the shot/collision/friction code changed at all. One real (if narrow) side effect WAS found and fixed regardless: picking which real recording to play drew from the exact same shared random-number pool the physics engine's own wobble/rebound/jump chances use, so playing more sounds during one shot could shift which random draw a LATER shot's own physics happened to get — sound now has its own completely separate random source, so it can never touch gameplay randomness again. If shots are still going wrong after this, that's not yet explained — please describe one as exactly as you can (which shot, does the on-screen aim line/arrow look right just before release, does it happen on a crowded board or an empty one) so it can actually be tracked down rather than guessed at. Second, "no sounds at all" again: total silence across every category (not just the specific ones from last time) points at the sound files themselves not being where the game expects them, most likely the audio.zip from last build either wasn't extracted yet or landed in the wrong spot — rather than lean on that step again, every individual sound file is now written directly into the audio folder in each of your three synced locations, no unzip required.) (Phase 100: "when discs go in a hole i hear no sound. when discs hit others i hear not sound. the slide sound of a disc on the board is way to quiet. what happened? did you not read y filenames. why is there now sounds when disc hit each other or fall in a hole. there is also no sound when a disc hits the backboard, i.e.. outside circle, outside the gutter. this should be loud when a fast disc hits it." Real, confirmed bugs in the Phase 99 real-sound-effects rebuild, found by instrumenting actual gameplay rather than guessing: (1) the loud backboard-thud sound was only ever wired to the rare "does it carom back into play" dice-roll the physics already had — the overwhelming majority of real edge-outs (a fast disc that reaches the wall and just settles in the gutter, which is what "hits the backboard" mostly means in practice) played nothing at all; it now fires, scaled loud for speed, on every disc that reaches the outer wall, rebound or not, with the gutter recordings demoted to a quieter settle-in accent layered underneath instead of standing in for the impact itself. (2) A disc grazing a fixed peg at a shallow angle can stay in contact for several consecutive physics steps, and each one was firing its own full-volume real recording — confirmed at up to 27 plays for what a player experiences as a single graze — which both sounded wrong on its own and was very likely starving genuinely separate sounds (a knock, a sink) moments later in the same shot of a free audio channel on a real machine, which is the most likely reason those read as silent even though the same code plays fine in isolation; every impact category now allows at most one real play within a short window, collapsing a graze back into the single knock a real board actually makes. (3) Every clip a cloned, unattached `
Crokinole Club
4 Player Singles · 5-Hole Board · 8 discs each

Board Type

Game Type

Number of Players

Play to what Score

Allow Ties

Forced Gambit Rules

Discs per Player

The tray space stays the same size — however many discs you pick are spread evenly across it.

Players & Colours

Seats

Drag a color chip onto a seat to place them, drag it off the diagram to unseat them, or drag a seated chip onto another seat to swap. Drag a row's ⠿ handle above to reorder the player list — the board rotates to match (whoever's first always sits at the bottom), and vice versa: rearranging seats on the board reorders the list too.

Who Goes First

Crokinole Scorekeeper
Track score on a scoreboard while you play

Scoreboard Type

Number of Players

Players & Colours

Scorekeeper
Drag a disc onto a hole to mark that player's score. Tap and hold, then drag.
Slo-Mo Replay
Zoom
20's
-10's
Results
Results
Viewing the board after that shot
Slo-Mo Replay
Searching for the best shot…