From d71628e087236e0efaf250ef123c8af603eb3931 Mon Sep 17 00:00:00 2001 From: Google AI Agent Date: Wed, 25 Mar 2026 03:06:52 +0000 Subject: [PATCH] [gemini] Re-implement Rune Ring (Portal-Tethered) (#476) (#496) Co-authored-by: Google AI Agent Co-committed-by: Google AI Agent --- app.js | 60 ++++++++++++++++++++++++++++++++++++---------------------- 1 file changed, 37 insertions(+), 23 deletions(-) diff --git a/app.js b/app.js index 057b668..67e9023 100644 --- a/app.js +++ b/app.js @@ -824,6 +824,33 @@ function createPortal(config) { light.position.set(0, 3.5, 1); group.add(light); + // Rune Ring (Portal-tethered) + const runeCount = 8; + const runeRingRadius = 4.5; + const runes = []; + for (let i = 0; i < runeCount; i++) { + const angle = (i / runeCount) * Math.PI * 2; + const runeGeo = new THREE.BoxGeometry(0.3, 0.8, 0.1); + const runeMat = new THREE.MeshStandardMaterial({ + color: portalColor, + emissive: portalColor, + emissiveIntensity: 0.8, + transparent: true, + opacity: 0.7, + roughness: 0.2, + metalness: 0.5, + }); + const rune = new THREE.Mesh(runeGeo, runeMat); + rune.position.set( + Math.cos(angle) * runeRingRadius, + 4, + Math.sin(angle) * runeRingRadius + ); + rune.rotation.y = angle + Math.PI / 2; + group.add(rune); + runes.push(rune); + } + // Label const labelCanvas = document.createElement('canvas'); labelCanvas.width = 512; @@ -863,7 +890,8 @@ function createPortal(config) { ring, swirl, pSystem, - light + light, + runes }; } @@ -989,20 +1017,7 @@ function createAmbientStructures() { scene.add(crystal); }); - for (let i = 0; i < 5; i++) { - const angle = (i / 5) * Math.PI * 2; - const r = 10; - const geo = new THREE.OctahedronGeometry(0.4, 0); - const mat = new THREE.MeshStandardMaterial({ - color: NEXUS.colors.primary, - emissive: NEXUS.colors.primary, - emissiveIntensity: 0.5, - }); - const stone = new THREE.Mesh(geo, mat); - stone.position.set(Math.cos(angle) * r, 5 + Math.sin(i * 1.3) * 1.5, Math.sin(angle) * r); - stone.name = 'runestone_' + i; - scene.add(stone); - } + const coreGeo = new THREE.IcosahedronGeometry(0.6, 2); const coreMat = new THREE.MeshPhysicalMaterial({ @@ -1430,6 +1445,12 @@ function gameLoop() { positions[i * 3 + 1] += Math.sin(elapsed + i) * 0.002; } portal.pSystem.geometry.attributes.position.needsUpdate = true; + + // Animate runes + portal.runes.forEach((rune, i) => { + rune.position.y = 4 + Math.sin(elapsed * 2 + i * 0.5) * 0.2; + rune.rotation.z = elapsed * 0.8 + i; + }); }); // Animate Vision Points @@ -1466,14 +1487,7 @@ function gameLoop() { dustParticles.rotation.y = elapsed * 0.01; } - for (let i = 0; i < 5; i++) { - const stone = scene.getObjectByName('runestone_' + i); - if (stone) { - stone.position.y = 5 + Math.sin(elapsed * 0.8 + i * 1.3) * 0.8; - stone.rotation.y = elapsed * 0.5 + i; - stone.rotation.x = elapsed * 0.3 + i * 0.7; - } - } + const core = scene.getObjectByName('nexus-core'); if (core) {