Skip to content

[33-games] two hands hold two blocks, game menus fit, phones start lighter, crisp VR panels - #260

Merged
AlexZ005 merged 5 commits into
feat/1.19from
feat/33-games
Oct 2, 2026
Merged

AlexZ005 merged 5 commits into
feat/1.19from
feat/33-games

Conversation

@AlexZ005

@AlexZ005 AlexZ005 commented Oct 1, 2026

Copy link
Copy Markdown
Collaborator

Roadmap 33, lane 33-games: items G1, G4, G5 and X1 from cloud plans/core/lanes/33/user-feedback-2026-10-01b.md. Includes a merge of origin/feat/1.18 (1.18.0). Do not merge until the integrator lands it.

# what was wrong fix proof
G4 Towers: two hands, two blocks vrControls had ONE grab slot. A second hand's grab overwrote it, and the first block stayed frozen in its kinematic physics hold until grabbed again. Per-hand grabs[]. A released body is dynamic at once; an input-source rebind releases the holds; vrGrabbedUuids() feeds the knock probe; vrGrabbedHand reads 'both' when both hands hold something. NEW vr-two-hand-grab 19/0 (fake XR + a running rapier sim). Counterfactual (old one-slot shape) gives 6 red, including the frozen crate. vr-grab 7, vr-grips-by-mode 18, knock-physics 77, vr-sleeve 29 still green.
G5 "Menu"/"Top strip" outside the panel The VR board footer needs 760 stage px, but a cropped game menu board is 720 wide. Menu sat at x -30 and Top strip ended at 1110 on a 1080 px canvas, in all 7 games. footerLayout() fits the buttons to the board. fitLabel() shrinks a label before it ever cuts one, and a cut is reported to the suites. NEW game-menu-layout: 7 games × desktop HUD per state + pause pages + VR board/shell/wrist bounds and gaps. Before: 7 red, exactly the footer. After: 28/0.
G1 Stars Room lags on phones The quality governor never acted on a phone. A 100-call game counts as LIGHT on desktop budgets, and a light scene is never governed, so a phone drew 32 render passes a frame at 2.6 Mpx. PHONE_START_LEVEL 4 (shadows off, 72 % resolution, AO off). Phones are judged heavy, as headsets already are. handleStamp/triggerStampFor use the edgesInto index; physics collectParams is indexed. scripts/perf-games.cjs --phone. Phone profile, CPU ×6, Stars Room: calls 101→47, passes 32→15, 2.60→0.65 Mpx, p50 50→33 ms, p99 200→83 ms. NEW quality-phone 10/0; counterfactual 5 red. game-stars-room 72/0.
X1 VR text crisp after 1.18 1.18 fixed the eye buffer. On top of that, the board canvas (0.78 texel per Quest 3 pixel) and the wrist card (0.60) were magnified. Board SCALE 2; wrist drawn at WRIST_RES 2. Every canvas panel is now ≥1.0 (board 1.06, wrist 1.31, strip 1.07, banner 1.13). NEW vr-panel-sharpness-all 10/0 (densities + a rendered edge-energy check). Counterfactual gives 3 red. vr-panel-sharpness 6, vr-game-panel 35, vr-laser-panels 25.

Gates on this branch: svelte-check 333/47 (baseline), vitest 381, check:storage clean, build green (server down). Held suites: game-stars-room 72, game-towers 21, vr-grab 7, game-shell-games 71, vr-game-panel 35.

Known, not this lane:

  • flow-physics-actions 8.5 fails identically on HEAD (A/B).
  • Untangle's "Board" setting row shows in every game's Settings once the module is installed (see QUESTIONS-33-games Feature/settings #3).

OWED on device: two-hand carry feel on a Quest; the board/wrist text and footer in the headset (and no hitch on hover at the bigger canvas); Stars Room on a real phone.

🤖 Generated with Claude Code

AlexZ005 and others added 5 commits October 1, 2026 19:54
- vrControls kept ONE grab slot. A second hand's grab overwrote it, so the first
  hand's piece stayed in its kinematic physics hold with nothing updating or
  releasing it: it hung in mid-air until a hand took it again (Towers report).
- grabs[] is indexed by controller slot; each hand updates and releases its own,
  a released body is dynamic at once. Two hands on the SAME object still scale it
  in Edit (and still do nothing extra in Interact).
- vrGrabbedHand reads 'both' while both hands hold; the two stick gates honour it.
- vrGrabbedUuids(): the knock probe skips everything the hands hold.
- an input-source rebind now RELEASES what the hands held instead of dropping the
  grab with the body still kinematic.
- new suite vr-two-hand-grab (19, fake XR + a running rapier sim).
  CF: clearing the other hand's slot on grab (the old single-slot shape) -> 6 red
  (1.1, 1.2, 2.2, 2.3, 2.5 hold user/bodyType 2 = the frozen crate, 2.12).
- vr-grab 7, vr-grips-by-mode 18, vr-source-rebind 5, knock-physics 77,
  vr-sleeve 29 green. svelte-check 333/47 unchanged.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…ons; menu layout audit (33 G5)

- The report: "Menu" and "Top strip" too close / outside the menu's border. Three
  240-stage-px footer buttons need 760 px while a cropped game menu board is 720 wide,
  so the row hung past BOTH edges (Menu at x -30, Top strip ending at 1110 on a 1080 px
  canvas) in all seven games.
- footerLayout(W, k, n): natural width when it fits, else the buttons share the board
  inside a side margin. fitLabel(): shrink a button label to fit, ellipsize only as a last
  resort and report it (collectOverflow -> vrGamePanelDebug().overflow). Used by the footer,
  the wrist card, the shell pages and a game screen's own buttons on the board.
- new suite game-menu-layout: the seven games (real .tpscene + real zips) x desktop HUD in
  every game state (inside the view, not half off a panel, 4 px apart), the pause menu's
  pages (inside the card, no overlap, no sideways scroll), the VR board per state + the
  shell pages on the board + the wrist (inside with a 10 px margin, 8 px apart, labels fit).
  BEFORE (HEAD's panel code): 7 red, exactly the reported footer (log + shots
  lanes-30/after-33/33-games/layout-before). AFTER run: see the handover.
- svelte-check 333/47 unchanged.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
… paths indexed (33 G1)

- The report: "Stars room is too heavy for mobile users, it lags". Measured on a phone
  profile (412x915 @2.625, isMobile + hasTouch, CPU x6, scripts/perf-games.cjs --phone):
  the governor sat at level 0 — a 100-call game is LIGHT by the desktop budgets and a light
  scene is never governed — so a phone drew 32 render passes a frame at 2.6 Mpx each
  (shadows, the authored AO, bloom, SMAA).
- qualityGovernorCore: PHONE_START_LEVEL = 4 (shadows off, 72 % resolution, AO off; the
  look stays) + pure isPhoneLike (coarse pointer, no hover, short side <= 820 CSS px).
  qualityGovernor: decided once at load; a phone starts there in auto mode (no floor - a
  phone that holds its frames walks back up) and context() judges it heavy, the headset's
  rule, so slow frames step it further. Auto off and a game's Quality pin still win.
- flowRuntime handleStamp/triggerStampFor read the existing edgesInto index instead of
  scanning every edge per call (24 latches x 3 handles x ~700 edges a tick); physics
  collectParams indexes nodes once (it was O(edges x nodes) on every flowGraphs change
  mid-sim). Both were top app frames in the Stars Room profile; gone after.
- Stars Room, phone profile before -> after: calls 101 -> 47, render passes 32.2 -> 15.3
  a frame, drawing buffer 2.60 -> 0.65 Mpx, p50 50 -> 33 ms, p99 200 -> 83 ms
  (lanes-30/after-33/33-games/perf-phone-{before,after}.md; Towers 83 -> 48 calls,
  p50 66.7 -> 33.3). A desktop GPU stands in for a phone's: a real phone reading is OWED.
- scripts/perf-games.cjs --phone (+ renders/frame, Mpx (dpr), physical/transparent columns).
- NEW suite quality-phone 10/0 (phone vs desktop page, the real Stars Room); CF (phone
  detection off) 5 red. vitest +3 (381). game-stars-room 72/0, logic-nodes 77/0.
  flow-physics-actions 8.5 is red IDENTICALLY on HEAD (A/B, both 35/2) - pre-existing.
  svelte-check 333/47.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
# Conflicts:
#	src/lib/qualityGovernor.js
#	src/lib/qualityGovernorCore.js
…all-panels sharpness probe (33 X1)

- 1.18 (merged) keeps the headset eye buffer full (b8a785f, vr-panel-sharpness 6/0 here).
  Extending the probe to EVERY canvas panel: text in a canvas is only as sharp as the
  canvas, so a texture stretched over more headset pixels than it has texels reads soft on
  a sharp eye buffer. Measured as texels per headset pixel (texelRatio, a Quest 3's ~25
  px/deg at the panel's real distance): board 0.78x and wrist card 0.60x were magnified;
  strip 1.07x and banner 1.13x already fine.
- vrGamePanel: SCALE 1.5 -> 2 (board + pause menu 1.06x at 1.2 m) and WRIST_RES 2 (the
  320x300 wrist layout drawn at 640x600 through drawCard's new `res`, hits returned in
  canvas px; 1.31x at 0.44 m). Layouts unchanged.
- NEW suite vr-panel-sharpness-all 10/0: board, pause menu, wrist, strip, banner at their
  real poses + every visible vr-* canvas mesh is in the probe + a rendered check (the wrist's
  text edge energy from the eye, full vs half its texels: x1.40). CF (SCALE 1.5, WRIST_RES 1)
  -> 3 red (0.80x / 0.65x / 0.80x). troika-Text panels (radial, objects, props, keyboard)
  are SDF and resolution independent.
- vr-game-panel 35, vr-laser-panels 25, vr-two-hand-grab 19, game-towers 21,
  game-shell-games 71, game-menu-layout 36 (re-run at the new scale) all green.
  svelte-check 333/47.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@AlexZ005
AlexZ005 merged commit 33cffe4 into feat/1.19 Oct 2, 2026
4 checks passed
@AlexZ005
AlexZ005 deleted the feat/33-games branch October 2, 2026 08:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant