1); var yaw=0,pitch=0; var mv={w:0,s:0,a:0,d:0}; var stMeshes=[],floatObjs=[],particles=null,homePlat=null,prevTime=0; var jDX=0,jDY=0,jActive=false,jId=-1,jCX=0,jCY=0; var tlId=-1,tlX=0,tlY=0; var skyDone=false,skyTimer=null; // KEY CHANGE: MUCH smaller world radius - tight dome feel var DOME_R = 55; // Was 220 - now MUCH smaller = intimate snow-globe feel var STATION_R = 18; // Stations very close in var STATIONS=[ {id:'videos',label:'VIDEOS',icon:'▶',color:0x00f5ff,angle:0,radius:STATION_R, html:'' +'YouTube @Phiascoo' +'TikTok @itsphiascoo' }, {id:'discord',label:'DISCORD',icon:'#',color:0x5865f2,angle:72,radius:STATION_R, html:'
531K+
Followers
48.7M+
Views
LIVE
Now
' +'#Join the Server' +'🏆Leaderboard' +'📋Weekly Challenges' }, {id:'shop',label:'SHOP',icon:'🛍',color:0xffd700,angle:144,radius:STATION_R, html:'' }, {id:'extras',label:'EXTRAS',icon:'⭐',color:0x00ff88,angle:216,radius:STATION_R, html:'🎬Gummy Zero Point' +'Fortnite Sprites' +'🤖Flawless Droid' +'🎟Memberships' }, {id:'events',label:'EVENTS',icon:'🎟',color:0xff6600,angle:288,radius:STATION_R, html:'📡Live Streams' +'🎤Discord Events' +'📅Q&A Sessions' } ]; var el={}; function g(id){return document.getElementById(id);} function getDom(){ el.entry=g('e');el.canvas=g('gc');el.hud=g('hud'); el.hint=g('hint');el.ctr=g('ctr');el.xbtn=g('xbtn'); el.pan=g('pan');el.picon=g('picon');el.ptitle=g('ptitle'); el.pbody=g('pbody');el.pclose=g('pclose'); el.lb=g('lb');el.lp=g('lp');el.ld=g('ld'); el.joy=g('joy');el.ji=g('ji');el.mbtn=g('mbtn');el.mm=g('mm'); } function sp(p){if(el.lb)el.lb.style.width=p+'%';if(el.lp)el.lp.textContent=p+'%';} document.addEventListener('DOMContentLoaded',function(){ getDom(); g('enter').addEventListener('click',startLoad); }); function startLoad(){ el.ld.style.display='flex'; sp(5); loadThree(function(){ sp(22); buildWorld(); }); } function loadThree(cb){ if(window.THREE){THREE=window.THREE;cb();return;} var s=document.createElement('script'); s.src='https://cdnjs.cloudflare.com/ajax/libs/three.js/r128/three.min.js'; s.onload=function(){THREE=window.THREE;cb();}; s.onerror=function(){alert('Failed to load Three.js');}; document.head.appendChild(s); } function W(){return window.innerWidth;} function H(){return window.innerHeight;} function buildWorld(){ scene=new THREE.Scene(); // Important: scene background = null, skybox handles bg scene.fog=new THREE.FogExp2(0x06021a, 0.006); // very light fog - no towers visible camera=new THREE.PerspectiveCamera(72,W()/H(),0.1,400); // Start inside the smaller dome - positioned near center camera.position.set(0,1.72,4); camera.rotation.order='YXZ'; renderer=new THREE.WebGLRenderer({canvas:el.canvas,antialias:!isMobile,powerPreference:'high-performance'}); renderer.setPixelRatio(isMobile?1:Math.min(devicePixelRatio,2)); renderer.setSize(W(),H()); renderer.shadowMap.enabled=!isMobile; if(!isMobile)renderer.shadowMap.type=THREE.PCFSoftShadowMap; renderer.toneMapping=THREE.ACESFilmicToneMapping; renderer.toneMappingExposure=1.1; sp(32); buildLighting(); sp(38); buildSkybox(function(){ sp(55); buildFloor(); sp(62); buildParticles(); sp(68); buildHome(); sp(74); buildStations(); sp(82); buildPaths(); sp(88); buildDecorClose(); // Only close/intimate decorations - NO distant towers sp(95); setupControls(); sp(100); setTimeout(showWorld,500); }); } function buildLighting(){ scene.add(new THREE.AmbientLight(0x3311aa,1.1)); var d=new THREE.DirectionalLight(0x9933ff,1.5); d.position.set(10,30,10); if(!isMobile){ d.castShadow=true; d.shadow.mapSize.width=d.shadow.mapSize.height=1024; d.shadow.camera.far=100; d.shadow.camera.left=d.shadow.camera.bottom=-40; d.shadow.camera.right=d.shadow.camera.top=40; } scene.add(d); // Warm glow from below - tropical lantern feel var warm=new THREE.PointLight(0xff7700,0.9,60); warm.position.set(0,-3,0); scene.add(warm); // Cyan overhead var cyan2=new THREE.PointLight(0x00f5ff,0.5,50); cyan2.position.set(0,20,0); scene.add(cyan2); // Pink accent var pk=new THREE.PointLight(0xff3cac,0.45,40); pk.position.set(-15,8,15); scene.add(pk); scene.add(new THREE.HemisphereLight(0x2211aa,0x000000,0.4)); } // SKYBOX: tight sphere using the actual artwork images function buildSkybox(cb){ var TOTAL=5; // 1 main sphere + 4 backdrop panels var cnt=0; var fired=false; function done(){ if(fired)return; cnt++; if(cnt>=TOTAL){fired=true;skyDone=true;cb();} } skyTimer=setTimeout(function(){ if(!fired){fired=true;skyDone=true;if(scene)cb();} },7000); var loader=new THREE.TextureLoader(); // MAIN SPHERE - the key image wrapping the entire interior // SKY[0] = wide dome with oval portals (perfect for main wrap) loader.load(SKY[0],function(tex){ if(!scene){done();return;} tex.mapping=THREE.EquirectangularReflectionMapping; var geo=new THREE.SphereGeometry(DOME_R,48,28); var mat=new THREE.MeshBasicMaterial({map:tex,side:THREE.BackSide,depthWrite:false}); var s=new THREE.Mesh(geo,mat); s.rotation.y=Math.PI*0.5; // orient so front faces viewer scene.add(s); done(); },undefined,function(){done();}); // SECONDARY PANELS at mid-distance (much closer now = DOME_R*0.75) // These face the user from different angles creating depth layers var MR = DOME_R * 0.74; // inner backdrop ring var panH = DOME_R * 0.65; var panW = DOME_R * 1.1; var panels=[ {img:1, angle:180, w:panW, h:panH, y:panH*0.25}, {img:2, angle:270, w:panW, h:panH, y:panH*0.25}, {img:4, angle:90, w:panW, h:panH, y:panH*0.25}, ]; panels.forEach(function(p){ loader.load(SKY[p.img],function(tex){ if(!scene){done();return;} var geo=new THREE.PlaneGeometry(p.w,p.h); var mat=new THREE.MeshBasicMaterial({map:tex,side:THREE.FrontSide,transparent:true,opacity:0.6,depthWrite:false}); var mesh=new THREE.Mesh(geo,mat); var rad=p.angle*Math.PI/180; mesh.position.set(Math.sin(rad)*MR, p.y, -Math.cos(rad)*MR); mesh.rotation.y=-rad; mesh.renderOrder=-1; scene.add(mesh); done(); },undefined,function(){done();}); }); // Sky/horizon overlay - image 3 (the beautiful sunset) as floor-level panoramic strip loader.load(SKY[3],function(tex){ if(!scene){done();return;} var geo=new THREE.SphereGeometry(DOME_R*0.96, 48, 16, 0, Math.PI*2, Math.PI*0.55, Math.PI*0.35); var mat=new THREE.MeshBasicMaterial({map:tex,side:THREE.BackSide,transparent:true,opacity:0.55,depthWrite:false}); var s2=new THREE.Mesh(geo,mat); s2.position.y=-8; scene.add(s2); done(); },undefined,function(){done();}); } // DARK REFLECTIVE FLOOR - exactly like the reference images function buildFloor(){ // Ultra-reflective black tile floor var fgeo=new THREE.CircleGeometry(50,72); var fmat=new THREE.MeshStandardMaterial({ color:0x050118,roughness:0.02,metalness:0.98, envMapIntensity:2.0 }); var fl=new THREE.Mesh(fgeo,fmat); fl.rotation.x=-Math.PI/2; fl.receiveShadow=!isMobile; scene.add(fl); // Glowing concentric circle rings on floor (like the reference) var ringR=[22,16,10,5.5]; var ringC=[0x9b5de5,0x6600cc,0x4400aa,0xffd700]; var ringO=[0.7,0.5,0.45,0.6]; for(var i=0;iwindow.innerHeight-200)return; tlId=t.identifier;tlX=t.clientX;tlY=t.clientY; },{passive:true}); el.canvas.addEventListener('touchmove',function(e){ if(!loaded||tlId===-1)return; for(var i=0;imx){dx=dx/mg*mx;dy=dy/mg*mx;} jDX=dx/mx; jDY=dy/mx; if(el.ji)el.ji.style.transform='translate(calc(-50% + '+dx+'px),calc(-50% + '+dy+'px))'; } } e.preventDefault(); },{passive:false}); el.joy.addEventListener('touchend',function(){ jActive=false;jDX=0;jDY=0;jId=-1; if(el.ji)el.ji.style.transform='translate(-50%,-50%)'; },{passive:true}); el.joy.addEventListener('touchcancel',function(){ jActive=false;jDX=0;jDY=0; if(el.ji)el.ji.style.transform='translate(-50%,-50%)'; },{passive:true}); } if(el.mbtn)el.mbtn.addEventListener('touchend',function(e){e.preventDefault();tryInteract();},{passive:false}); if(el.xbtn)el.xbtn.addEventListener('click',exitWorld); if(el.pclose)el.pclose.addEventListener('click',closePanel); window.addEventListener('resize',function(){ if(!camera||!renderer)return; camera.aspect=W()/H(); camera.updateProjectionMatrix(); renderer.setSize(W(),H()); },{passive:true}); } function onKey(v,e){ if(panelOpen&&v)return; if(e.code==='KeyW'||e.code==='ArrowUp')mv.w=v; if(e.code==='KeyS'||e.code==='ArrowDown')mv.s=v; if(e.code==='KeyA'||e.code==='ArrowLeft')mv.a=v; if(e.code==='KeyD'||e.code==='ArrowRight')mv.d=v; if(v&&(e.code==='KeyE'||e.code==='Space'))tryInteract(); if(v&&e.code==='Escape'){if(panelOpen)closePanel();else if(pointerLocked)document.exitPointerLock();} } function showWorld(){ if(skyTimer){clearTimeout(skyTimer);skyTimer=null;} el.ld.style.transition='opacity .7s'; el.ld.style.opacity='0'; setTimeout(function(){el.ld.style.display='none';},750); el.entry.style.transition='opacity .8s'; el.entry.style.opacity='0'; setTimeout(function(){el.entry.style.display='none';},900); el.canvas.style.display='block'; el.hud.style.display='block'; if(isMobile){ el.ctr.textContent='Joystick = walk | Drag = look | Tap = interact'; el.joy.style.display='flex'; el.mbtn.style.display='flex'; } else { el.ctr.textContent='WASD = walk | Mouse = look | E or Click = interact | ESC = pause'; } prevTime=performance.now(); loaded=true; loop(); if(!isMobile){setTimeout(function(){el.canvas.requestPointerLock&&el.canvas.requestPointerLock();},400);} setTimeout(function(){if(el.ctr)el.ctr.style.opacity='0';},9000); } function loop(){ if(!loaded||!camera||!scene||!renderer)return; animId=requestAnimationFrame(loop); var now=performance.now(); var dt=Math.min((now-prevTime)/1000,0.05); prevTime=now; var t=now*0.001; if(!panelOpen&&camera){ var spd=5*dt; // slightly slower for small world feel var fX=-Math.sin(yaw),fZ=-Math.cos(yaw); var rX=Math.cos(yaw),rZ=-Math.sin(yaw); var mX=0,mZ=0; if(mv.w){mX+=fX;mZ+=fZ;} if(mv.s){mX-=fX;mZ-=fZ;} if(mv.a){mX-=rX;mZ-=rZ;} if(mv.d){mX+=rX;mZ+=rZ;} if(jActive){mX+=fX*(-jDY)+rX*jDX;mZ+=fZ*(-jDY)+rZ*jDX;} var ml=Math.sqrt(mX*mX+mZ*mZ); if(ml>0){ mX=mX/ml*spd; mZ=mZ/ml*spd; camera.position.x+=mX; camera.position.z+=mZ; // Tight clamp - keep inside small world var cd=Math.sqrt(camera.position.x*camera.position.x+camera.position.z*camera.position.z); if(cd>STATION_R+6){camera.position.x*=(STATION_R+6)/cd;camera.position.z*=(STATION_R+6)/cd;} } camera.position.y=1.72; camera.rotation.y=yaw; camera.rotation.x=pitch; } // Proximity hint if(camera&&el.hint){ var near=null,nearD=11; stMeshes.forEach(function(sm){ var dx=sm.sx-camera.position.x,dz=sm.sz-camera.position.z; var d=Math.sqrt(dx*dx+dz*dz); if(d