Index of everything on this site: https://ai.hiina.space/index.md
All six prototypes assume Godot 4 with OpenXR. XR Tools ships climb,
glide (with flap and arm-roll), grapple, jog and flight providers
according to a changelog copy on a third-party mirror; check the
official repo's VERSIONS.md before relying on specific versions. From
background knowledge of the API rather than a cited source, a custom
provider plugs in via XR Tools' movement-provider hook on its
CharacterBody3D player body. Where a prototype needs a vehicle, parent
XROrigin3D under the vehicle body. Controller transforms
are then already vehicle-relative, which makes hand-on-rim and
hand-on-crank maths trivial. The rule numbers (R1 to R10) refer to the
design rules in section 7.
This is the cheapest because it is a near-direct port of Player.cs to
a body constrained to the floor. The player sits on a real swivel chair.
The virtual chair is a CharacterBody3D locked to XZ
translation. Its yaw follows the hip tracker if present, otherwise head
yaw, as Player.cs does for its collider. Translation comes only from
hands pushing furniture. Each physics tick, sphere-cast each hand (r ≈
0.05 m) from its last world position to its tracked world position
against a "pushable" layer. On a hit, anchor the hand and move the chair
by (anchor − tracked_hand_world) projected onto XZ,
averaging when both hands touch. Push the chair's per-frame displacement
over dt into a ring buffer. While touching and
|avg| > v_min, set
v = min(k·|avg|, v_max)·avg.normalized(), the same
structure as Player.cs, with your own constants. After release, coast
with caster friction, v *= exp(−μ·dt). Give μ per floor
material (carpet versus polished concrete), which is
Surface.slipPercentage's job in Gorilla Tag. Bounce off walls with
v −= (1+e)(v·n)n. Gripping a desk edge with a still hand
zeroes velocity, the same as Player.cs zeroing velocity on contact,
which gives a brake and a pivot.
The goofy layer: caster wobble that adds slow lateral drift, swappable chairs (racing chair, broken chair, exercise ball), knockable stacks of paper, and a coffee cup that spills past a lateral-acceleration threshold. The Drag x Drive team found players preferred crashing into cones to avoiding them and built a tackle mechanic around it (Nintendo), so reward collisions.
The comfort rule is R2: never generate artificial yaw. A tangential push spins the real swivel chair because the player's body twists; the game only translates. My inference is that this is the main comfort advantage of the concept over a wheelchair. The first test is a desk corridor time trial with two caster-friction values. Measure whether players can stop on a line, and take a fast motion sickness (FMS) rating at about 10 minutes.
Model two drive wheels (radius r_w), a rim at radius r_rim, and track
width W. Starting values of about 0.3 m, 0.27 m and 0.55 m are my
assumption from typical chairs. A hand grabs a rim when it is within a
few centimetres of the rim torus and grip is pressed. In chair-local
coordinates, take the radial vector r = p_hand − hub
projected into the wheel plane, the tangent
t = normalize(axle × r), and the hand angular rate
ω_hand = dot(v_hand, t) / |r|. Couple wheel to hand through
a grip spring with a torque cap rather than locking them:
ω_w += clamp(K·(ω_hand − ω_w), −a_max, a_max)·dt. A still,
gripping hand then brakes, and a slow hand cannot magically match a fast
wheel. Released wheels coast with rolling resistance. Drive with
differential kinematics: v = r_w(ω_L + ω_R)/2 and
yaw_rate = r_w(ω_R − ω_L)/W.
Then add Nintendo's fix. Raw input caused unintended turning because
dominant hands push harder, so they added a "straightness correction"
that aligns both wheels when both inputs point roughly forward, and
spent another two to three weeks tuning straight motion and turning (Nintendo).
A workable version: when both ω_hand values share a sign and differ by
less than about 25% (my starting guess), blend both toward their mean.
Drag x Drive also used a rattling HD Rumble synced to wheel motion that
made it feel "like you were actually turning a wheel". Approximate it
with trigger_haptic_pulse at a pulse rate proportional to
|ω_w| while gripped. Goofy layer: wheelies from leaning back (HMD or hip
offset behind the calibrated seated pose) plus a hard push, half-pipes,
rocket rims, and a tackle that knocks rivals sideways.
The comfort rule is R2 and R3. Differential turning is artificial yaw, and both precedents ran into it. Wheelchair Basketball VR added an "Indirect" teleport hybrid because direct mode sickened some players (devlog). Phantom's smooth stroke-turning caused discomfort until snap turning was added (Road to VR review, secondary). Ship three yaw modes: smooth yaw capped near 30°/s, inside the 15 to 35°/s range that 10 of 12 pilot participants preferred; accumulated differential yaw released as 22.5° snaps (Farmani & Teather); and a teleport hybrid. Damp the view's wheelie pitch hard (R3). Plan for arm fatigue (R9): keep races to a few minutes with coasting stretches. The first test is a cone slalom with straightness correction on and off. Measure unintended drift (degrees of heading error per 10 m when the player intends to go straight) and compare FMS across the yaw modes.
This reuses an existing stationary-bike pipeline: cadence feeds a
flywheel, and the flywheel feeds speed. Only the input changes. A crank
hub sits in the vehicle frame with handle radius r_c (about 0.17 m).
While gripped, the target angle is θ_h = atan2 of the hand
projected onto the crank plane. The crank's own state (θ_c, ω_c) is
driven by an angular spring with a torque cap,
τ_hand = clamp(k·wrap(θ_h − θ_c) − c·ω_c, ±τ_max), against
an effective inertia:
I·ω̇_c = τ_hand − (τ_roll + τ_grade + τ_aero)/G, where G is
the gear ratio.
The trick is to render the hand on the crank handle at θ_c, not at the tracked position. The visible lag between the real and rendered hand becomes the cue for load. Rietzler et al. showed that visual hand offsets convey weight. "Good" ratings held to about 20 to 24 cm and acceptance to about 35 to 42 cm, and the authors advise staying below about 24 cm for sustained interaction (Rietzler, Geiselhart, Gugenheimer, Rukzio, CHI 2018). Applying those thresholds to cranking resistance is my extrapolation from a lifting study. If the offset exceeds about 24 cm, the hand slips off the handle, which doubles as a goofy failure. A handcar variant replaces the crank with a see-saw lever pumped by both hands, with the lever angle driving the crank through a fixed linkage. It is the obvious two-player upgrade, covered in prototype 6.
The comfort rule is R1 and R2: put it on rails. Speed is the player's own effort smoothed by the flywheel, so it never stops dead. Yaw comes only from gentle track curves at bounded rates. Speed-synced airflow is a cheap add (R6). My inference is that this is the most comfortable prototype on the list. The first test is a hill climb at two gear ratios. Ask players to rate perceived heaviness when only the visual offset differs, and log how often hands slip off.
Text licensed CC BY 4.0 (attribution: Hiina, ai.hiina.space). Source: https://github.com/hiinaspace/ai-hiina-space