Relief: Saddle and Basin
Software checks passed; two-phone acceptance is pending. No physical-device sample rate, accelerometer range, toss accuracy or gravity-leakage result has been invented. Endorsement remains with U. Warring after the two-phone measurements. The game is a physics-based scenario, not a calibrated specimen.
What is implemented
One continuous landscape, 4 route passes, two drainage holes, a curved low wall across the board, an undrained walled pocket, a sandy pothole, an amber resin patch and a gentle goal summit. Full motion feeds measured phone acceleration into the same contact/flight solver. There are no shake, toss or stuck-state detectors. The existing five balls, four floor choices and two wall materials remain available; the level acceptance scope is the five balls on hardwood. Other whole-board floors are exploratory and are not claimed solvable at 8°.
Motion defaults to tilt only. In Materials & play choose Full motion, then Enable tilt and calibrate. A button during play switches modes without resetting the run. The comfortable tilt budget defaults to 8° and can be set from 4° to 15°; lowering it does not regenerate or recertify the level. Touch and keyboard control tilt only. Full motion requires valid device motion data.
Board-frame dynamics
n = (−hₓ, −hᵧ, 1) / √(1 + |∇h|²)
N = m max[0, −geff·n − v·dn/dt]
u = v + ω × (−rn)
aroll ≈ [g t − a∥ − (g + aup)∇h] / (1 + k), k = I/(mr²)
The normal-load estimate sets rolling and granular losses. Unilateral contact impulses provide the reaction and Coulomb friction, so curvature is not applied twice. Finite sphere radius is included through the normal-offset surface: a circular crest uses Rc + r, a dip Rc − r [1]. Solid balls recover 5/7; the hollow shell recovers 3/5. Static friction limits the rolling impulse; otherwise kinetic friction opposes contact slip and changes spin.
When support is lost, translation follows geff and quadratic air drag. Angular velocity remains constant until contact; the visible quaternion keeps rotating. Landing uses restitution against the local normal, followed by slip and re-grip. Airborne translation uses a midpoint update. Before restitution, the solver removes gravitational work accumulated after crossing the surface, preventing a numerical tiny-bounce limit cycle in the hollow ball.
This is the task card’s translational-inertia plus virtual-tilt approximation. It omits Euler, Coriolis and centrifugal terms of a fully rotating board, sensor-to-board lever-arm corrections and a moving-air model. Rapid wrist rotation can therefore violate its validity even if terrain slopes remain below 15°. Calibrated β/γ differences set virtual tilt; absolute β/γ are used separately to subtract sensor gravity. Full motion is not a claim of complete six-degree-of-freedom reconstruction.
What the accelerometer supplies
adevice = s · accelerationIncludingGravity − frest,device, s = ±1 measured at calibration
The browser quantity is specific force: in the specification a face-up resting device reports approximately +g in z, and free fall approximately zero [2]. WebKit, the engine of every iPhone browser, passes Core Motion’s opposite sign through, so a face-up iPhone reports −g on all three axes. Calibration therefore measures s: while the phone is held still, the mean reading is compared with frest,device from the same β/γ. A match within 0.1g, directly or negated, fixes s for later samples. Otherwise full motion stays off until the next calibration. The remaining difference is reported as the rest residual. The user agent is not consulted. The engine subtracts the orientation-derived resting specific force before screen-axis remapping. A minimal yaw-free rotation maps measured physical gravity to calibrated virtual gravity and applies the same orthogonal map to linear acceleration. This preserves free-fall equivalence at pitched calibration; it does not scale acceleration amplitudes. It does not use DeviceMotionEvent.acceleration. Pose samples are interpolated when bracketed and extrapolated for at most 25 ms from recent orientation changes; a held pose is used when orientation events are unchanged. Timestamp alignment cannot remove unknown sensor-fusion delay.
Timestamped acceleration samples are held over physics substeps and split at sample boundaries. A sample older than 100 ms is no longer applied; pausing clears the held input. Linear acceleration magnitude is capped at 3g while preserving direction. Physics uses a 240 Hz outer clock, internal steps no longer than 1/960 s and displacement bounds of r/5. Resume gaps contribute at most 50 ms. Tilt filtering remains 15 ms; acceleration is not low-pass filtered.
Debug recording reports all three acceleration axes, normal load, contact/flight state, delivered sample rate, pose age, observed axis peaks, cap counts and suspected repeated high-amplitude flat tops. A flat top can also be real motion or quantization: it is not proof of clipping. DeviceMotion exposes no hardware full-scale range. Observed peaks are lower bounds; no automatic amplitude boost or guessed per-phone calibration changes the physics.
The finite-stop correction
A 0.4 m/s upward motion followed by uniform deceleration over 30 ms produces about 2.15 mm maximum separation above the final board position, not 8 mm. Relative speed is initially zero at separation and grows while the board stops. For a sufficiently strong uniform stop, h = v²/(2g) − vT/2. The 8.15 mm value assumes an instantaneous stop. The regression uses the specified finite waveform and checks separation and height within 5%.
The route bot uses a declared jump-region acceleration fixture: 0.65√s m/s carried speed, 0.15√s s half-sine acceleration and a 0.025√s s stop, plus a 3 m/s² in-plane pulse for 0.1√s s toward the route, where s is board scale. This stays below the 3g cap; it is stronger than the task card’s illustrative 0.4 m/s flick. No velocity is injected into the ball. The fixture is a test input, not a button or detector in the game. Real 60 Hz sampling may materially distort such a short stop, so its repeatability remains a phone gate.
Landscape construction and acceptance
Six oriented anisotropic Gaussians form the main landscape, with additional Gaussian confinement depressions, low-amplitude domain-warped trigonometric noise and a declared compact launch lip. The start shelf and goal are smoothly blended. The constructor reduces terrain amplitude to satisfy slope and non-lip curvature bounds while preserving the goal’s central curvature. Candidates then face independent geometric, pocket and bot gates; failed candidates are rejected. A deliberately closed starting enclosure is rejected by the same bot.
The height grid has at most 2.5 mm cells on the 30 × 63.3 cm reference board. Bicubic Hermite coefficients give shared first derivatives across cells. Height, gradient and Hessian differentiate the same interpolated potential; independently interpolating gradients was avoided because it can disconnect force from potential energy. Terrain is C¹ at grid seams; small curvature discontinuities remain. The lip is the declared exception to broad feature wavelength and crest-radius limits.
| Accepted geometry | Value |
|---|---|
| Seed | 371 |
| Maximum terrain slope | 13.0693° |
| Minimum non-lip crest radius | 106.469 mm |
| Maximum uphill slope on route | 8.72349° |
| Route passes | 4 |
| Goal e-folding reference | 0.700 s |
| Goal dwell | 3 s, whole ball within ring; centre within 2r |
Each material retains its physical ball size, so the board scales with radius. The reference steel, rubber and cork balls now have 5 mm radius; table tennis and billiards retain their nominal sizes. The goal’s curvature is adjusted for each inertia and radius to keep the lossless central e-folding reference at 0.7 s. Rolling resistance creates a material-dependent deadband; cork and sand may settle. The summit is not forced unstable by a hidden force.
Drainage, confinement and patches
Critical-point and gradient-flow analysis finds broad catchment minima and saddle clearances. Holes are placed at those minima, at least 3r from saddles. A separate grid of 20 rigid-body releases at zero tilt, with holes removed, checks actual settling. Both broad basins are observed. 14 of 20 releases settle within a hole-radius of a broad minimum; other outcomes remain in the record. Momentum can cross a topographic watershed, so a gradient-flow basin map is not an inertial trajectory prediction.
Explicit exception to “every basin gets a hole”: the pocket and sandy pothole remain undrained, otherwise they could not serve as confinement features. In the pocket test, 30 seconds of constant exit-directed 8° tilt does not escape. Adding one 5 m/s², 0.1 s board pulse while keeping that tilt frees the ball. This finite controller test does not prove that every possible resonant tilt sequence is incapable of escape. No jamming flag or state latch exists.
The resin patch is a spatial loss profile, not a new selectable material. Rolling-moment arm b₀/r is 0.20, or 0.28 for rubber. It holds both balls at 8°; the reference pulse moves both, with steel sliding farther. Steel-like patch grip is μs = 0.28, μk = 0.12; rubber uses 0.95 and 0.70. These are uncalibrated scenario coefficients. The sandy pothole reuses the sand model.
Walls are polylines with local terrain-relative heights 2r and 6r. Collision is against vertical curtains and their rounded sphere–edge geometry, so the ball’s bottom can clear a wall and a top-edge landing is a rim contact rather than a flat plateau. Open edges remains optional; it removes the perimeter curtains and allows a physical drop off the finite board, followed by the 800 ms restart.
Sculpt: player edits (draft)
Sculpt ends the current run and lets the player reshape the relief in a build phase; leaving it starts a new run from the start shelf. Edits are node deltas (h, ∂h/∂x, ∂h/∂y, ∂²h/∂x∂y) on the relief’s own 2.5 mm Hermite grid, stored in steel-board coordinates and added to every ball’s field when it is sampled, with heights × scale and curvature ÷ scale. The edited board is still one C¹ potential whose gradient and Hessian feed the unchanged contact solver. Without edits the arithmetic, and so every relief result above, is unchanged.
The brush is a compact Mexican hat, C² at its rim, with zero net volume: a dip inside 0.447R and a berm of 0.216a peaking at 0.632R. Holding deposits half the flat-ground limit per second, in brush ticks of 50 ms of stroke time, so the result does not depend on the frame rate. A drag spreads each tick over stamps at most R/8 apart, so a slow drag ploughs deeper than a fast one. Near a board edge a stamp is mirrored across it, which keeps the net volume zero and the edge level. A C² mask fades edits to exactly zero, over 30 mm, around the start shelf, the hole rims and the goal. The goal zone covers the whole 83 mm blend in which each ball’s summit curvature is tuned, so bounds checked on the steel field hold for every ball. Only next to those zones is a press not volume-neutral.
Each tick is scaled by the largest α in [0, 1] that keeps the slope at most tan 14.6°, the crest curvature at most 20 m⁻¹ and the hollow curvature at most 50 m⁻¹, or no worse than the relief where it already exceeds a bound, as at the lip. The check samples 3 × 3 points on each changed cell’s own polynomial; between them the tests measured crest curvature up to 1.1% over the bound. The crest bound is relaxed from the relief generator’s 9.65 m⁻¹ so that presses make features of several millimetres: on a level crest a 5 mm ball keeps contact up to √(g(1/κ + r)) ≈ 0.73 m/s instead of 1.03 m/s, and a faster ball hops through the existing flight model. The hollow bound keeps rκ ≤ 0.25, half the curvature at which the support solver was checked correct on one geometry.
| Brush | Radius R [mm] | Dig limit, level ground [mm] | Pile limit, level ground [mm] |
|---|---|---|---|
| S | 40 | 2.42896 | 2 |
| M | 60 | 5.07282 | 4.5 |
| L | 90 | 7.60923 | 7.60923 |
An edited board is labelled as edited and has not been checked: the drainage, pocket and route evidence apply to the unedited relief only, and player-made basins get no holes. Strokes are stored as 0.5 mm integer paths with the applied α, and undo, reset and reload replay them bit for bit within one JavaScript engine. Edits are autosaved in this browser only. Pressure is not read; hold time stands in for it. Editing never happens while the ball moves, so no moving-surface contact is needed.
Material coefficients and dimensions
| Ball | Diameter [mm] | Mass [g] | Bulk density [kg/m³] | I / mr² | Board [cm] |
|---|---|---|---|---|---|
| Steel | 10 | 4.13643 | 7900 | 0.4 | 30 × 63.3333 |
| Bouncy rubber | 10 | 0.575959 | 1100 | 0.4 | 30 × 63.3333 |
| Table tennis | 40 | 2.7 | 80.5722 | 0.666667 | 120 × 253.333 |
| Cork | 10 | 0.125664 | 240 | 0.4 | 30 × 63.3333 |
| Billiard | 57.15 | 170 | 1739.41 | 0.4 | 171.45 × 361.95 |
Table-tennis nominal 40 mm / 2.7 g dimensions follow ITTF T3 [3], with ideal shell inertia 2mr²/3. Other balls use homogeneous-sphere inertia 2mr²/5. Steel, rubber and cork densities are selected as 7,900, 1,100 and 240 kg/m³; billiards uses 57.15 mm / 170 g. Sizes are explicit, not inferred from apparent pixels.
| Contact pair | μs / μk / μimpact | e at 1 m/s | Tangential e | b₀ [μm] | b₁ [μs] | Effective E* [Pa] |
|---|---|---|---|---|---|---|
| Steel / Hardwood | 0.25 / 0.18 / 0.2 | 0.55 | 0 | 8 | 12 | 1000000000 |
| Steel / Dry sand | 0.55 / 0.4 / 0.4 | 0.05 | 0 | 8 | 12 | 1000000000 |
| Steel / Smooth ice | 0.03 / 0.025 / 0.025 | 0.55 | 0 | 0 | 0 | 1000000000 |
| Steel / Baize | 0.25 / 0.2 / 0.2 | 0.35 | 0 | 126 | 0 | 10000000 |
| Bouncy rubber / Hardwood | 0.85 / 0.65 / 0.7 | 0.85 | 0.45 | 40 | 50 | 5000000 |
| Bouncy rubber / Dry sand | 0.8 / 0.6 / 0.6 | 0.12 | 0 | 40 | 50 | 5000000 |
| Bouncy rubber / Smooth ice | 0.1 / 0.07 / 0.08 | 0.78 | 0.25 | 8 | 10 | 5000000 |
| Bouncy rubber / Baize | 0.85 / 0.65 / 0.65 | 0.65 | 0.2 | 262.5 | 20 | 3000000 |
| Table tennis / Hardwood | 0.25 / 0.2 / 0.2 | 0.85 | 0.1 | 30 | 20 | 10000000 |
| Table tennis / Dry sand | 0.45 / 0.3 / 0.3 | 0.12 | 0 | 30 | 20 | 10000000 |
| Table tennis / Smooth ice | 0.04 / 0.03 / 0.03 | 0.82 | 0.05 | 0 | 0 | 10000000 |
| Table tennis / Baize | 0.3 / 0.2 / 0.2 | 0.65 | 0.1 | 500 | 0 | 5000000 |
| Cork / Hardwood | 0.6 / 0.45 / 0.45 | 0.28 | 0 | 120 | 100 | 2000000 |
| Cork / Dry sand | 0.6 / 0.45 / 0.45 | 0.05 | 0 | 120 | 100 | 2000000 |
| Cork / Smooth ice | 0.08 / 0.06 / 0.06 | 0.25 | 0 | 30 | 30 | 2000000 |
| Cork / Baize | 0.65 / 0.45 / 0.45 | 0.2 | 0 | 315 | 50 | 1000000 |
| Billiard / Hardwood | 0.25 / 0.2 / 0.2 | 0.6 | 0 | 30 | 20 | 1000000000 |
| Billiard / Dry sand | 0.55 / 0.4 / 0.4 | 0.05 | 0 | 30 | 20 | 1000000000 |
| Billiard / Smooth ice | 0.04 / 0.03 / 0.03 | 0.65 | 0 | 0 | 0 | 1000000000 |
| Billiard / Baize | 0.25 / 0.2 / 0.2 | 0.4 | 0 | 400.05 | 0 | 10000000 |
| Contact pair | μs / μk / μimpact | e at 1 m/s | Tangential e | b₀ [μm] | b₁ [μs] | Effective E* [Pa] |
|---|---|---|---|---|---|---|
| Steel / Hardwood | 0.25 / 0.18 / 0.2 | 0.55 | 0 | 8 | 12 | 1000000000 |
| Steel / Rubber bumpers | 0.7 / 0.55 / 0.55 | 0.88 | 0.15 | 8 | 12 | 3000000 |
| Bouncy rubber / Hardwood | 0.85 / 0.65 / 0.7 | 0.85 | 0.45 | 40 | 50 | 5000000 |
| Bouncy rubber / Rubber bumpers | 0.9 / 0.75 / 0.75 | 0.88 | 0.4 | 40 | 50 | 3000000 |
| Table tennis / Hardwood | 0.25 / 0.2 / 0.2 | 0.85 | 0.1 | 30 | 20 | 10000000 |
| Table tennis / Rubber bumpers | 0.6 / 0.45 / 0.45 | 0.9 | 0.2 | 30 | 20 | 3000000 |
| Cork / Hardwood | 0.6 / 0.45 / 0.45 | 0.28 | 0 | 120 | 100 | 2000000 |
| Cork / Rubber bumpers | 0.7 / 0.5 / 0.5 | 0.35 | 0 | 120 | 100 | 3000000 |
| Billiard / Hardwood | 0.25 / 0.2 / 0.2 | 0.6 | 0 | 30 | 20 | 1000000000 |
| Billiard / Rubber bumpers | 0.14 / 0.14 / 0.14 | 0.98 (constant) | 0 | 30 | 20 | 3000000 |
Rolling loss is torque N[b₀ + b₁r|ωtangent|], with separate torsional loss. There is no global damping or speed clamp. Hertz contact radius estimates torsional friction only; it does not predict restitution. The static near-rest tolerance is 20 μm/s. Restitution is suppressed below 0.08 m/s normal contact speed. The general interpolation e(v) = [1 + (1/eref − 1)(v / 1 m s⁻¹)¹ᐟ⁵]⁻¹ is a motivated scenario law [6], not a universal fit. Billiard–rubber instead uses constant e = 0.98.
Billiard–baize sliding friction 0.20 and rolling deceleration 0.01g reproduce pooltool reference defaults [4], with b₀ = (1+k)r × 0.01. Billiard–rubber e = 0.98 and μ = 0.14 are borrowed from Mathavan et al. [5]; that paper’s cushion geometry differs from these curtains. All other contact values remain assumptions.
Fplough = 0.18Nδ/r Mbed = 0.12Nδ
Finertial = 1.5ρbedA(δ)|v|²
Fair = −½(1.225)(0.47)πr²|v|v
Granular penetration scales from a glass-bead experiment [7]; applying it to a shallow sand layer, hollow shells and cork is unvalidated. The load factor N/(mg) is a quasi-static extension with no relaxation or compaction memory. Sinkage affects resistance without moving the surface. Air drag uses fixed density and drag coefficient; Reynolds dependence, Magnus lift and air spin loss are omitted. The optional oil film remains deferred.
Rendering and audio
Fixed-light hillshade uses display slope exaggeration ×20 and one global contour interval equal to the unedited terrain’s height range divided by eight, fixed per ball so that an edit changes only its own contours. There are no terrain labels. Colours identify sand and resin; darker wood identifies the pocket wall. Taller curtains cast longer shadows. The ball’s shadow stays at its ground projection while apparent ball position, scale and shadow spread vary with clearance. Quaternion marks reveal spin.
Procedural floor texture, hillshade, contours and walls are cached, and a Sculpt edit redraws only the rectangle it changed; marks and the ball are composited per frame. Canvas backing density stays capped at 2, with safe-area and visualViewport handling. Add to Home Screen remains the recommended iPhone launch path. Audio is driven by speed, slip and contact impulses; it is sound design, not measured acoustic calibration. Silent mode is respected where supported. Optional haptics remain feature-detected.
Reproducible results and remaining gates
| Ball on hardwood | Completed trials |
|---|---|
| Steel | 10 / 10 |
| Bouncy rubber | 10 / 10 |
| Table tennis | 10 / 10 |
| Cork | 10 / 10 |
| Billiard | 10 / 10 |
The bot is bounded to 8°, uses PD control with terrain feed-forward and seeded initial positions, and supplies acceleration only inside declared jump regions. These repeats test small initial perturbations; they are not independent human trials or a sensor-noise/latency model. The hardest tested ball by completion/time was Billiard. All five passed 10/10. Whole-board sand or other floor swaps are not included in that acceptance claim.
113 automated regression checks cover contact/energy, inertia, gravity removal, held samples, the finite toss waveform, normal-load grip changes, ballistic jump table, confinement, resin, drainage, goal dwell, open edges, cached drawing execution, audio scheduling and the Sculpt edit layer (volume, bounds, keep-outs, replay and redraw). The 40 older material routes are retained only as a non-playable regression fixture; the new level has its own acceptance trials. Renderer/audio API test doubles do not establish actual pixels or audible quality.
Complete acceptance record · Generator and rejected candidate record · Complete SI parameter ledger
| Required phone test | Status |
|---|---|
| Phone 1 | pending — sample rate, peaks, clipping and motion behaviour unmeasured |
| Phone 2 | pending — sample rate, peaks, clipping and motion behaviour unmeasured |
On each phone: enable tilt and Full motion; record a stationary baseline, a 30° tilt over 0.3 s with no intended translation, in-plane pulses and upward flicks. Compare measured gravity leakage with 0.3 m/s², inspect sample timing and suspected clipping, and play the route in tilt-only and full modes. Diagnostics → Clear motion → select scenario → perform motion → Export motion JSON. Logs remain local until explicitly downloaded/shared. Pose/acceleration fusion delay and hardware range cannot be certified from the synthetic test. Browser visual, listening, two-phone and physical-specimen validation remain pending.
Sources
- University of Illinois Dynamics Reference: rolling motion, normal-offset curvature and rolling kinematics; Feynman Lectures: two rolling balls, inertia-dependent acceleration.
- W3C Device Orientation and Motion, device coordinates, specific force, orientation and event definitions. Sensor subtraction and latency claims are separated from measured results.
- ITTF T3 (2014), nominal table-tennis dimensions and steel-block bounce specification; historical primary specification.
- Pooltool v0.3.3 BallParams, reference defaults, not our experimental data.
- Mathavan, Jackson & Parkin, Billiard ball dynamics under cushion impacts (2010).
- Ramírez et al., Coefficient of restitution of colliding viscoelastic spheres (1999); R. Cross, Impact behavior of a superball (2015), and Coulomb’s law for rolling friction (2016).
- Energy dissipation of a sphere rolling up a granular slope, Physical Review E 109, 014903 (2024); transfer to this bed remains extrapolation.
- WebKit Safari 26.0; AudioSession.type; Navigator.vibrate, platform feature boundaries.