Monorepo for Aesthetic.Computer aesthetic.computer
4
fork

Configure Feed

Select the types of activity you want to include in your feed.

arena: press F to cycle hover axis-flip experiment (NONE/X/Z/XZ)

Adds a runtime toggle for the hover raycast's axis-sign convention so
we can A/B all four combinations without recompiling. Current default
is Z-only flip (kept from last experiment since it fixed one axis).
HUD shows the active mode (F:NONE / F:X / F:Z / F:XZ) in the top-right.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

+31 -10
+31 -10
system/public/aesthetic.computer/disks/arena.mjs
··· 50 50 let lastHitWorld = null; // [x, z] or null 51 51 let lastPenScreen = null; // [x, y] or null 52 52 53 + // Axis-sign experiment toggle. Press F to cycle. See the hover raycast for 54 + // what each bit flips. 55 + // 0 = baseline 1 = flipX 56 + // 2 = flipZ 3 = flip both 57 + let hoverFlipMode = 2; // current best guess: Z flipped per experiments 58 + 53 59 // ⚡ Adaptive-quality flags driven by measured render FPS. Auto-toggle in 54 60 // paint() based on the rolling frame-time average. Pieces can override via the 55 61 // HUD labels (future: click to pin). "LOW" = coarser tile, static lava, skip ··· 552 558 lastHitWorld = null; 553 559 lastPenScreen = penLocked ? null : [mx, my]; 554 560 if (fy < -0.001) { 555 - // EXPERIMENT: Z convention flip test. If the raycast hits the wrong tile 556 - // mirrored across the player, flipping Z in both ray origin AND direction 557 - // is a point reflection across the XY plane through origin. If this 558 - // makes the hover tile correct, we know Z-axis in engine is inverted 559 - // from what my derivation assumed. (Direction-only or origin-only flips 560 - // would not cause a clean mirror; we need both or neither.) 561 - const camWorldX = -cam.x; 561 + // Ray origin + direction. The hoverFlipMode toggle lets us A/B all four 562 + // axis-sign combinations without editing source — press F to cycle. 563 + // 0 = no flip (baseline derivation) 564 + // 1 = flip X (hit.x) 565 + // 2 = flip Z (hit.z) 566 + // 3 = flip both 567 + const flipX = (hoverFlipMode & 1) !== 0; 568 + const flipZ = (hoverFlipMode & 2) !== 0; 569 + const camWorldX = flipX ? cam.x : -cam.x; 562 570 const camWorldY = -cam.y; 563 - const camWorldZ = cam.z; // was -cam.z (flipped) 564 - const fzAdj = -fz; // flipped direction 571 + const camWorldZ = flipZ ? cam.z : -cam.z; 572 + const fxAdj = flipX ? -fx : fx; 573 + const fzAdj = flipZ ? -fz : fz; 565 574 const t = (GROUND_Y - camWorldY) / fy; 566 575 if (t > 0 && t < 200) { 567 - const hitX = camWorldX + t * fx; 576 + const hitX = camWorldX + t * fxAdj; 568 577 const hitZ = camWorldZ + t * fzAdj; 569 578 hoverTile = tileAt(hitX, hitZ); 570 579 lastHitWorld = [hitX, hitZ]; ··· 801 810 if (perfLowMode) rightLabel("-BODY -ANIM", margin + lineH * 7); 802 811 else if (perfMedMode) rightLabel("-LAVA-ANIM", margin + lineH * 7); 803 812 813 + // Hover-flip experiment — press F to cycle, label shows current mode. 814 + const flipNames = ["F:NONE", "F:X", "F:Z", "F:XZ"]; 815 + ink(255, 200, 80); 816 + rightLabel(flipNames[hoverFlipMode], margin + lineH * 8); 817 + 804 818 // Speed meter (bottom-center). speedSmoothed is per-sim-tick position delta; 805 819 // sim runs at SIM_HZ, so ups = perTickDelta * SIM_HZ. 806 820 const ups = speedSmoothed * SIM_HZ; ··· 856 870 function act({ event: e, penLock, system }) { 857 871 if (e.is("pen:locked")) penLocked = true; 858 872 if (e.is("pen:unlocked")) penLocked = false; 873 + 874 + // F cycles the hover axis-flip experiment (0 = no flip, 1 = X, 2 = Z, 3 = both). 875 + if (e.is("keyboard:down:f")) { 876 + hoverFlipMode = (hoverFlipMode + 1) & 3; 877 + console.log("🔄 hoverFlipMode →", hoverFlipMode, 878 + ["baseline", "flipX", "flipZ", "flipBoth"][hoverFlipMode]); 879 + } 859 880 860 881 // 🎥 Middle-mouse toggles third-person (press once to enter, press again 861 882 // to exit). Only trigger on touch so the release doesn't also flip.