SIMON Master Console Rebuild
True command center for SIMON + WEB360
This rebuild gives you a cleaner production spine: interactive tree, live viewer, guarded editor, dynamic graphics, architecture map, and note storage. It is designed to sit beside your existing
console.php
and become the stronger replacement path.
Dashboard
Tree
Viewer
System Map
File Registry
Notes
Files
15,680
Folders
433
Scanned Size
3.89 GB
PHP Files
988
Editable Text Files
12,938
File viewer
guarded to /htdocs
/downloads/Escape.html
<!doctype html> <html lang="en"> <head> <meta charset="utf-8" /> <meta name="viewport" content="width=device-width,initial-scale=1,viewport-fit=cover" /> <title>The Wicked Game — 3D Reality Escape</title> <meta name="theme-color" content="#050816" /> <style> :root{ --bg:#050816; --bg2:#091127; --panel:rgba(255,255,255,.08); --panel2:rgba(255,255,255,.05); --edge:rgba(255,255,255,.14); --txt:#eef4ff; --mut:#a9b8dd; --cyan:#6ae0ff; --indigo:#7b62ff; --pink:#ff4fd6; --green:#44d18a; --warn:#ffcc4d; --danger:#ff5f7a; --shadow:0 25px 80px rgba(0,0,0,.45); } *{box-sizing:border-box} html,body{height:100%} body{ margin:0; overflow:hidden; color:var(--txt); font-family:Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,Roboto,Arial,sans-serif; background: radial-gradient(1000px 500px at 50% -10%, rgba(123,98,255,.25), transparent 60%), radial-gradient(900px 500px at 100% 100%, rgba(255,79,214,.10), transparent 55%), radial-gradient(900px 500px at 0% 100%, rgba(106,224,255,.09), transparent 55%), linear-gradient(180deg, var(--bg2), var(--bg)); } #fx,#world{position:fixed; inset:0; width:100%; height:100%; display:block} #fx{z-index:0} #world{z-index:1; perspective:1200px; overflow:hidden} .vignette{ position:fixed; inset:0; z-index:2; pointer-events:none; background:radial-gradient(circle at center, transparent 35%, rgba(0,0,0,.20) 68%, rgba(0,0,0,.58) 100%); mix-blend-mode:multiply; } .grid3d, .stars, .tunnel, .layer-wrap, .debris-wrap{ position:absolute; inset:-20%; transform-style:preserve-3d; } .grid3d{ background: linear-gradient(rgba(106,224,255,.12) 1px, transparent 1px), linear-gradient(90deg, rgba(106,224,255,.12) 1px, transparent 1px); background-size:56px 56px; transform:rotateX(78deg) translateZ(-420px); filter:drop-shadow(0 0 18px rgba(106,224,255,.14)); animation:gridScroll 9s linear infinite; opacity:.85; } @keyframes gridScroll{ from{background-position:0 0,0 0} to{background-position:0 56px,56px 0} } .stars::before,.stars::after{ content:""; position:absolute; inset:0; background-repeat:repeat; background-image: radial-gradient(circle, rgba(255,255,255,.95) 0 1px, transparent 1.5px), radial-gradient(circle, rgba(106,224,255,.9) 0 1px, transparent 1.5px), radial-gradient(circle, rgba(255,79,214,.75) 0 1px, transparent 1.5px); background-size:140px 140px, 220px 220px, 300px 300px; background-position:0 0, 30px 50px, 80px 20px; opacity:.9; } .stars::after{ transform:translateZ(-600px) scale(1.3); opacity:.45; filter:blur(1px); } .tunnel{ transform-style:preserve-3d; transform:translateZ(-200px); } .ring{ position:absolute; left:50%; top:50%; border-radius:50%; border:2px solid rgba(106,224,255,.18); box-shadow:0 0 18px rgba(106,224,255,.16), inset 0 0 24px rgba(123,98,255,.08); transform-style:preserve-3d; } .layer{ position:absolute; border-radius:22px; background:linear-gradient(180deg, rgba(255,255,255,.12), rgba(255,255,255,.03)); border:1px solid rgba(255,255,255,.14); box-shadow:0 18px 50px rgba(0,0,0,.25), inset 0 0 30px rgba(106,224,255,.05); backdrop-filter:blur(4px); } .layer.glitch{box-shadow:0 0 40px rgba(255,79,214,.15), 0 0 70px rgba(106,224,255,.10)} .layer.exit{border-color:rgba(68,209,138,.6); box-shadow:0 0 24px rgba(68,209,138,.30), inset 0 0 22px rgba(68,209,138,.18)} .layer.orb{border-radius:50%} .beam{ position:absolute; width:4px; border-radius:999px; background:linear-gradient(180deg, rgba(106,224,255,0), rgba(106,224,255,.75), rgba(255,79,214,.18), rgba(106,224,255,0)); box-shadow:0 0 18px rgba(106,224,255,.35); transform-origin:center top; } .debris{ position:absolute; border-radius:8px; background:linear-gradient(180deg, rgba(123,98,255,.6), rgba(106,224,255,.18)); border:1px solid rgba(255,255,255,.12); box-shadow:0 0 16px rgba(123,98,255,.18); } .hud{ position:fixed; inset:16px 16px auto 16px; z-index:5; display:grid; gap:12px; grid-template-columns:minmax(280px,420px) auto; align-items:start; } .panel{ border:1px solid var(--edge); background:linear-gradient(180deg, var(--panel), var(--panel2)); box-shadow:var(--shadow); border-radius:22px; backdrop-filter:blur(12px) saturate(130%); } .hero{padding:18px 18px 16px} .hero h1{margin:0 0 6px; font-size:clamp(28px,4vw,54px); line-height:.95; letter-spacing:.03em} .hero p{margin:0; color:var(--mut); max-width:56ch} .chips{display:flex; flex-wrap:wrap; gap:8px; margin-top:14px} .chip{padding:8px 12px; border-radius:999px; border:1px solid var(--edge); background:rgba(255,255,255,.05); font-size:12px; color:var(--mut)} .brand{display:inline-flex; align-items:center; gap:10px; margin-bottom:10px; font-size:12px; color:var(--mut); text-transform:uppercase; letter-spacing:.22em} .dot{width:10px; height:10px; border-radius:50%; background:var(--cyan); box-shadow:0 0 0 8px rgba(106,224,255,.12), 0 0 18px rgba(106,224,255,.40)} .stats{padding:14px; display:grid; gap:10px} .row{display:grid; grid-template-columns:repeat(4,minmax(88px,1fr)); gap:10px} .stat{padding:12px; border-radius:16px; background:rgba(0,0,0,.20); border:1px solid rgba(255,255,255,.10)} .stat b{display:block; font-size:11px; color:var(--mut); text-transform:uppercase; letter-spacing:.12em; margin-bottom:5px} .stat span{font-size:20px; font-weight:800} .controls{display:flex; flex-wrap:wrap; gap:10px; padding:0 14px 14px} button{ appearance:none; border:1px solid var(--edge); background:rgba(255,255,255,.06); color:var(--txt); cursor:pointer; padding:12px 14px; border-radius:15px; font-weight:700; letter-spacing:.02em; box-shadow:0 10px 25px rgba(0,0,0,.20); } button.primary{background:linear-gradient(180deg, rgba(123,98,255,.42), rgba(106,224,255,.16)); border-color:rgba(106,224,255,.30)} button.good{border-color:rgba(68,209,138,.35)} button.warn{border-color:rgba(255,204,77,.35)} .statusbar{ position:fixed; left:16px; right:16px; bottom:16px; z-index:5; display:grid; grid-template-columns:1.4fr 1fr; gap:12px; } .log{padding:12px 14px; min-height:90px} .log b{display:block; font-size:11px; color:var(--mut); text-transform:uppercase; letter-spacing:.14em; margin-bottom:8px} .logText{font-size:15px; line-height:1.35} .meters{padding:12px 14px} .meter{margin:8px 0} .meter label{display:flex; justify-content:space-between; font-size:12px; color:var(--mut); margin-bottom:6px} .bar{height:12px; border-radius:999px; background:rgba(255,255,255,.07); border:1px solid rgba(255,255,255,.09); overflow:hidden} .fill{height:100%; width:40%; background:linear-gradient(90deg, var(--cyan), var(--indigo), var(--pink)); box-shadow:0 0 16px rgba(106,224,255,.30)} .help{ position:fixed; top:16px; right:16px; z-index:5; padding:12px 14px; width:min(360px, calc(100vw - 32px)); } .help b{display:block; font-size:11px; color:var(--mut); text-transform:uppercase; letter-spacing:.14em; margin-bottom:8px} .help p{margin:0 0 10px; font-size:14px; color:var(--mut)} .help ul{margin:0; padding-left:18px; color:var(--txt)} .help li{margin:6px 0} .flash{ position:fixed; inset:0; z-index:4; pointer-events:none; opacity:0; background:radial-gradient(circle at center, rgba(106,224,255,.14), rgba(123,98,255,.08), rgba(255,79,214,.05), transparent 65%); } .flash.on{animation:flash .45s ease} @keyframes flash{0%{opacity:0}40%{opacity:1}100%{opacity:0}} .win{ position:fixed; inset:0; display:none; place-items:center; z-index:8; background:rgba(3,8,18,.72); backdrop-filter:blur(10px); } .win.on{display:grid} .card{ width:min(760px,92vw); padding:26px; border-radius:26px; border:1px solid rgba(255,255,255,.14); background:linear-gradient(180deg, rgba(255,255,255,.09), rgba(255,255,255,.04)); box-shadow:var(--shadow); } .card h2{margin:0 0 10px; font-size:clamp(26px,4vw,46px)} .card p{color:var(--mut); font-size:16px} .card .actions{display:flex; gap:10px; flex-wrap:wrap; margin-top:16px} @media (max-width:960px){ .hud{grid-template-columns:1fr} .statusbar{grid-template-columns:1fr} .help{position:fixed; top:auto; bottom:190px; right:16px} .row{grid-template-columns:repeat(2,1fr)} } @media (max-width:640px){ .help{display:none} .hero p{font-size:14px} button{padding:11px 12px} } </style> </head> <body> <canvas id="fx"></canvas> <div id="world" aria-hidden="true"> <div class="stars"></div> <div class="grid3d"></div> <div class="tunnel" id="tunnel"></div> <div class="layer-wrap" id="layers"></div> <div class="debris-wrap" id="debris"></div> </div> <div class="flash" id="flash"></div> <div class="vignette"></div> <section class="hud"> <div class="panel hero"> <div class="brand"><span class="dot"></span> The Wicked Game // SIMON Escape Layer</div> <h1>Reality is a system.<br>Break its rules.</h1> <p>The player discovers the world is simulated. Each stage exposes another hidden layer. Bend time, distort gravity, and rewrite physics to escape the machine.</p> <div class="chips"> <span class="chip">3D graphics</span> <span class="chip">time manipulation</span> <span class="chip">gravity shift</span> <span class="chip">law rewrite</span> <span class="chip">SIMON system logic</span> </div> </div> <div class="panel stats"> <div class="row"> <div class="stat"><b>Layer</b><span id="layerNum">01</span></div> <div class="stat"><b>Time Flux</b><span id="timeNum">1.00x</span></div> <div class="stat"><b>Gravity</b><span id="gravNum">Normal</span></div> <div class="stat"><b>Rule State</b><span id="ruleNum">Stable</span></div> </div> <div class="controls"> <button class="primary" id="startBtn">Start Escape</button> <button id="timeBtn">Manipulate Time</button> <button id="gravityBtn">Alter Gravity</button> <button id="rewriteBtn">Rewrite Physics</button> <button class="good" id="scanBtn">Reveal Hidden Layer</button> <button class="warn" id="resetBtn">Reset</button> </div> </div> </section> <aside class="panel help"> <b>How to Play</b> <p>Reach the green exit node while the system keeps mutating. Survive long enough to expose all hidden layers and escape.</p> <ul> <li><strong>W A S D</strong> or <strong>Arrow Keys</strong> move</li> <li><strong>Shift</strong> boost through unstable zones</li> <li><strong>T</strong> slows or speeds time</li> <li><strong>G</strong> rotates gravity axis</li> <li><strong>R</strong> rewrites world laws</li> <li><strong>Space</strong> scans for the exit path</li> </ul> </aside> <section class="statusbar"> <div class="panel log"> <b>System Transmission</b> <div class="logText" id="logText">SIMON: The simulation is masking the exit. Start the sequence and force hidden layers to reveal themselves.</div> </div> <div class="panel meters"> <div class="meter"> <label><span>Escape Progress</span><span id="progressValue">0%</span></label> <div class="bar"><div class="fill" id="progressFill" style="width:0%"></div></div> </div> <div class="meter"> <label><span>Reality Integrity</span><span id="integrityValue">86%</span></label> <div class="bar"><div class="fill" id="integrityFill" style="width:86%"></div></div> </div> <div class="meter"> <label><span>Signal Noise</span><span id="noiseValue">24%</span></label> <div class="bar"><div class="fill" id="noiseFill" style="width:24%"></div></div> </div> </div> </section> <div class="win" id="winScreen"> <div class="card"> <h2>You escaped the layer stack.</h2> <p>The system bent, fractured, and exposed its hidden architecture. This is a strong prototype direction for your <em>Wicked Game</em>: cinematic 3D layers, shifting physics, moving exits, and SIMON transmissions guiding the player out of a synthetic world.</p> <div class="actions"> <button class="primary" id="playAgainBtn">Play Again</button> <button id="closeWinBtn">Continue Viewing</button> </div> </div> </div> <script> (() => { const world = document.getElementById('world'); const tunnel = document.getElementById('tunnel'); const layersWrap = document.getElementById('layers'); const debrisWrap = document.getElementById('debris'); const fx = document.getElementById('fx'); const ctx = fx.getContext('2d'); const flash = document.getElementById('flash'); const logText = document.getElementById('logText'); const layerNum = document.getElementById('layerNum'); const timeNum = document.getElementById('timeNum'); const gravNum = document.getElementById('gravNum'); const ruleNum = document.getElementById('ruleNum'); const progressFill = document.getElementById('progressFill'); const progressValue = document.getElementById('progressValue'); const integrityFill = document.getElementById('integrityFill'); const integrityValue = document.getElementById('integrityValue'); const noiseFill = document.getElementById('noiseFill'); const noiseValue = document.getElementById('noiseValue'); const winScreen = document.getElementById('winScreen'); const startBtn = document.getElementById('startBtn'); const timeBtn = document.getElementById('timeBtn'); const gravityBtn = document.getElementById('gravityBtn'); const rewriteBtn = document.getElementById('rewriteBtn'); const scanBtn = document.getElementById('scanBtn'); const resetBtn = document.getElementById('resetBtn'); const playAgainBtn = document.getElementById('playAgainBtn'); const closeWinBtn = document.getElementById('closeWinBtn'); const clamp = (n,min,max) => Math.max(min, Math.min(max, n)); const rnd = (a,b) => a + Math.random() * (b - a); const state = { started:false, t:0, dt:0, timeMode:0, timeScale:1, gravityMode:0, rewriteMode:0, scanPulse:0, integrity:86, noise:24, progress:0, layer:1, maxLayer:6, tiltX:0, tiltY:0, camZ:0, vx:0, vy:0, x:0, y:0, boost:false, exitVisible:false, won:false }; const keys = new Set(); const rings = []; const layers = []; const debris = []; const particles = []; function sizeFX(){ const dpr = Math.max(1, Math.min(2, devicePixelRatio || 1)); fx.width = Math.floor(innerWidth * dpr); fx.height = Math.floor(innerHeight * dpr); fx.style.width = innerWidth + 'px'; fx.style.height = innerHeight + 'px'; ctx.setTransform(dpr,0,0,dpr,0,0); } addEventListener('resize', sizeFX, {passive:true}); sizeFX(); function pulseFlash(){ flash.classList.remove('on'); void flash.offsetWidth; flash.classList.add('on'); } function setLog(msg){ logText.textContent = msg; } function buildTunnel(){ tunnel.innerHTML = ''; rings.length = 0; for(let i=0;i<22;i++){ const el = document.createElement('div'); el.className = 'ring'; const size = 180 + i * 54; el.style.width = size + 'px'; el.style.height = size + 'px'; tunnel.appendChild(el); rings.push({ el, z: -i * 220, size, spin:rnd(-1.2,1.2) }); } } function randomLayerType(i){ if (i === state.maxLayer - 1) return 'exit'; const bag = ['glitch','wall','beam','orb','wall','beam','glitch']; return bag[i % bag.length]; } function buildLayers(){ layersWrap.innerHTML = ''; layers.length = 0; for(let i=0;i<state.maxLayer;i++){ const type = randomLayerType(i); const el = document.createElement('div'); const z = -600 - i * 520; let x = rnd(-240,240); let y = rnd(-130,130); let w = rnd(90,220); let h = rnd(90,220); if(type === 'beam'){ w = 4; h = rnd(160,320); } if(type === 'orb'){ w = h = rnd(80,160); } if(type === 'exit'){ x = rnd(-120,120); y = rnd(-80,80); w = h = 150; } el.className = 'layer ' + (type === 'wall' ? '' : type); el.style.width = w + 'px'; el.style.height = h + 'px'; layersWrap.appendChild(el); layers.push({ el, type, x, y, z, w, h, baseX:x, baseY:y, active:i===0 || type==='exit', phase:rnd(0,6.28), speed:rnd(.6,1.6) }); } } function buildDebris(){ debrisWrap.innerHTML = ''; debris.length = 0; for(let i=0;i<80;i++){ const el = document.createElement('div'); el.className = 'debris'; const s = rnd(10,28); el.style.width = s + 'px'; el.style.height = s * rnd(.7,1.4) + 'px'; debrisWrap.appendChild(el); debris.push({ el, x:rnd(-700,700), y:rnd(-420,420), z:rnd(-4000,300), rx:rnd(0,360), ry:rnd(0,360), rz:rnd(0,360), drift:rnd(.4,1.6) }); } } function resetParticles(){ particles.length = 0; for(let i=0;i<180;i++){ particles.push({ x:rnd(0,innerWidth), y:rnd(0,innerHeight), vx:rnd(-.4,.4), vy:rnd(-.4,.4), r:rnd(.8,2.8), o:rnd(.08,.32), hue:rnd(180,320) }); } } function resetGame(){ state.started = false; state.t = 0; state.timeMode = 0; state.timeScale = 1; state.gravityMode = 0; state.rewriteMode = 0; state.scanPulse = 0; state.integrity = 86; state.noise = 24; state.progress = 0; state.layer = 1; state.x = 0; state.y = 0; state.vx = 0; state.vy = 0; state.camZ = 0; state.exitVisible = false; state.won = false; buildTunnel(); buildLayers(); buildDebris(); updateHUD(); setLog('SIMON: Sequence reset. The simulation is stable again — for now.'); winScreen.classList.remove('on'); } function updateHUD(){ layerNum.textContent = String(state.layer).padStart(2,'0'); timeNum.textContent = state.timeScale.toFixed(2) + 'x'; gravNum.textContent = ['Normal','Left','Inverted','Right'][state.gravityMode]; ruleNum.textContent = ['Stable','Fractured','Unbound'][state.rewriteMode]; progressFill.style.width = state.progress + '%'; progressValue.textContent = Math.round(state.progress) + '%'; integrityFill.style.width = state.integrity + '%'; integrityValue.textContent = Math.round(state.integrity) + '%'; noiseFill.style.width = state.noise + '%'; noiseValue.textContent = Math.round(state.noise) + '%'; } function startGame(){ state.started = true; setLog('SIMON: Hidden geometry detected. Move through the layer stack. Use time, gravity, and law rewrites to reveal the exit.'); pulseFlash(); } function manipulateTime(){ state.timeMode = (state.timeMode + 1) % 3; state.timeScale = [0.55, 1.0, 1.65][state.timeMode]; state.noise = clamp(state.noise + 8, 0, 100); state.integrity = clamp(state.integrity - 5, 0, 100); setLog([ 'SIMON: Time drag engaged. Motion is slowing across the system.', 'SIMON: Time restored to baseline frequency.', 'SIMON: Temporal acceleration active. Use the instability while it lasts.' ][state.timeMode]); updateHUD(); pulseFlash(); } function alterGravity(){ state.gravityMode = (state.gravityMode + 1) % 4; state.noise = clamp(state.noise + 6, 0, 100); state.integrity = clamp(state.integrity - 4, 0, 100); setLog('SIMON: Gravity axis re-routed to ' + ['normal','left pull','inverted pull','right pull'][state.gravityMode] + '.'); updateHUD(); pulseFlash(); } function rewritePhysics(){ state.rewriteMode = (state.rewriteMode + 1) % 3; state.noise = clamp(state.noise + 10, 0, 100); state.integrity = clamp(state.integrity - 8, 0, 100); for (const layer of layers) { if (layer.type !== 'exit') { layer.baseX += rnd(-120,120); layer.baseY += rnd(-80,80); } } setLog([ 'SIMON: Physical law remains coherent — barely.', 'SIMON: Collision rules fractured. Obstacles are beginning to drift.', 'SIMON: The world is unbound. Geometry no longer trusts itself.' ][state.rewriteMode]); updateHUD(); pulseFlash(); } function scanLayer(){ state.scanPulse = 1; state.noise = clamp(state.noise + 5, 0, 100); state.exitVisible = true; for(let i=0;i<layers.length;i++) layers[i].active = i < state.layer + 1 || layers[i].type === 'exit'; setLog('SIMON: Hidden layer scan complete. Exit path signal increased. Keep moving.'); pulseFlash(); updateHUD(); } function win(){ if (state.won) return; state.won = true; state.progress = 100; updateHUD(); setLog('SIMON: Escape sequence successful. The system shell has been breached.'); winScreen.classList.add('on'); pulseFlash(); } function collideRect(px, py, obj){ const hw = obj.w/2, hh = obj.h/2; return px > obj.x - hw && px < obj.x + hw && py > obj.y - hh && py < obj.y + hh; } function updatePlayer(dt){ let ax = 0, ay = 0; const speed = state.boost ? 740 : 460; if(keys.has('arrowleft') || keys.has('a')) ax -= 1; if(keys.has('arrowright') || keys.has('d')) ax += 1; if(keys.has('arrowup') || keys.has('w')) ay -= 1; if(keys.has('arrowdown') || keys.has('s')) ay += 1; if (state.gravityMode === 1) ax -= .5; if (state.gravityMode === 2) ay -= .6; if (state.gravityMode === 3) ax += .5; const len = Math.hypot(ax, ay) || 1; ax /= len; ay /= len; state.vx += ax * speed * dt; state.vy += ay * speed * dt; state.vx *= 0.88; state.vy *= 0.88; state.x = clamp(state.x + state.vx * dt, -300, 300); state.y = clamp(state.y + state.vy * dt, -180, 180); } function updateProgress(dt){ const exit = layers.find(l => l.type === 'exit'); const dist = Math.hypot(state.x - exit.x, state.y - exit.y); if (dist < 180) { state.progress = clamp(state.progress + dt * 16 + (180 - dist) * 0.012, 0, 100); if (state.progress >= ((state.layer / state.maxLayer) * 100) && state.layer < state.maxLayer) { state.layer++; setLog('SIMON: Layer ' + state.layer + ' exposed. The system is losing concealment.'); pulseFlash(); } } if (state.layer >= state.maxLayer && dist < 80) win(); } function updateWorld(dt){ state.t += dt * state.timeScale; state.scanPulse = Math.max(0, state.scanPulse - dt * 1.6); const wobble = Math.sin(state.t * 1.3) * 4; world.style.transform = `perspective(1200px) rotateX(${state.tiltX * 0.7}deg) rotateY(${state.tiltY * 0.9}deg)`; rings.forEach((r, i) => { const z = r.z + ((state.t * 300 * state.timeScale) % 220); const spin = state.t * r.spin * 40; r.el.style.transform = `translate3d(-50%,-50%,${z}px) rotateZ(${spin}deg) scale(${1 + Math.sin(state.t + i)*0.04})`; r.el.style.borderColor = `rgba(${90 + i*2}, ${200 - i*3}, 255, ${0.08 + (i % 3) * 0.04})`; }); layers.forEach((o, i) => { const driftX = Math.sin(state.t * o.speed + o.phase) * (o.type === 'beam' ? 120 : 46) * (state.rewriteMode + 1) * 0.38; const driftY = Math.cos(state.t * (o.speed * 0.8) + o.phase) * 34 * (state.rewriteMode + 1) * 0.45; o.x = o.baseX + driftX; o.y = o.baseY + driftY; const visible = o.active || (o.type === 'exit' && state.exitVisible); o.el.style.display = visible ? 'block' : 'none'; const scale = o.type === 'exit' ? 1 + state.scanPulse * 0.18 + Math.sin(state.t * 3) * 0.04 : 1; const extraRot = (o.type === 'orb' ? state.t * 65 : state.t * 16) + (i * 8); const glow = o.type === 'exit' ? 'drop-shadow(0 0 30px rgba(68,209,138,.45))' : `drop-shadow(0 0 ${10 + state.rewriteMode * 8}px rgba(106,224,255,.18))`; o.el.style.filter = glow; o.el.style.transform = `translate3d(calc(50vw + ${o.x}px - ${o.w/2}px), calc(50vh + ${o.y}px - ${o.h/2}px), ${o.z + wobble * i}px) rotateX(${extraRot * 0.4}deg) rotateY(${extraRot}deg) rotateZ(${extraRot * 0.25}deg) scale(${scale})`; o.el.style.opacity = visible ? (o.type === 'exit' ? 1 : 0.92) : 0; }); debris.forEach((d, i) => { d.z += (160 + d.drift * 100) * dt * state.timeScale; if (d.z > 240) d.z = -4200; d.rx += d.drift * 35 * dt; d.ry += d.drift * 52 * dt; d.rz += d.drift * 29 * dt; const x = d.x + Math.sin(state.t * .7 + i) * 28; const y = d.y + Math.cos(state.t * .5 + i) * 18; d.el.style.transform = `translate3d(calc(50vw + ${x}px), calc(50vh + ${y}px), ${d.z}px) rotateX(${d.rx}deg) rotateY(${d.ry}deg) rotateZ(${d.rz}deg)`; d.el.style.opacity = clamp(1 - ((d.z + 4200) / 4600), .12, .95); }); const exit = layers.find(l => l.type === 'exit'); if (state.started && !state.won) { for (const o of layers) { if (!o.active || o.type === 'exit') continue; if (collideRect(state.x, state.y, o)) { state.integrity = clamp(state.integrity - dt * (8 + state.rewriteMode * 5), 0, 100); state.noise = clamp(state.noise + dt * 14, 0, 100); } } updateProgress(dt); state.integrity = clamp(state.integrity - dt * .7 + (state.timeMode===0 ? .6*dt : 0), 0, 100); state.noise = clamp(state.noise + dt * (.8 + state.rewriteMode * .7), 0, 100); if (state.integrity <= 0) { setLog('SIMON: Reality integrity collapsed. Restart the sequence.'); resetGame(); } if (state.noise > 70 && !state.exitVisible) state.exitVisible = true; } const playerMarker = layersWrap.querySelector('[data-player]') || (() => { const el = document.createElement('div'); el.dataset.player = '1'; el.className = 'layer orb'; el.style.width = '44px'; el.style.height = '44px'; el.style.background = 'radial-gradient(circle at 35% 35%, rgba(255,255,255,.9), rgba(106,224,255,.45), rgba(123,98,255,.18), transparent 75%)'; el.style.borderColor = 'rgba(106,224,255,.55)'; el.style.boxShadow = '0 0 20px rgba(106,224,255,.45), inset 0 0 20px rgba(255,255,255,.2)'; layersWrap.appendChild(el); return el; })(); playerMarker.style.transform = `translate3d(calc(50vw + ${state.x}px - 22px), calc(50vh + ${state.y}px - 22px), 120px) scale(${state.boost ? 1.25 : 1})`; } function drawFX(dt){ ctx.clearRect(0,0,innerWidth,innerHeight); const grad = ctx.createRadialGradient(innerWidth/2, innerHeight/2, 20, innerWidth/2, innerHeight/2, Math.max(innerWidth, innerHeight) * .6); grad.addColorStop(0, 'rgba(106,224,255,.08)'); grad.addColorStop(.4, 'rgba(123,98,255,.06)'); grad.addColorStop(.8, 'rgba(255,79,214,.03)'); grad.addColorStop(1, 'rgba(0,0,0,0)'); ctx.fillStyle = grad; ctx.fillRect(0,0,innerWidth,innerHeight); ctx.save(); ctx.globalCompositeOperation = 'lighter'; particles.forEach((p,i) => { p.x += p.vx * (1 + state.timeMode * .5); p.y += p.vy * (1 + state.timeMode * .5); p.x += Math.sin(state.t + i) * .25; p.y += Math.cos(state.t * .7 + i) * .25; if(p.x < -20) p.x = innerWidth + 20; if(p.x > innerWidth + 20) p.x = -20; if(p.y < -20) p.y = innerHeight + 20; if(p.y > innerHeight + 20) p.y = -20; ctx.fillStyle = `hsla(${p.hue + Math.sin(state.t + i) * 25}, 100%, 70%, ${p.o})`; ctx.beginPath(); ctx.arc(p.x, p.y, p.r + state.scanPulse * 1.8, 0, Math.PI * 2); ctx.fill(); }); ctx.strokeStyle = `rgba(106,224,255,${0.16 + state.scanPulse * .25})`; ctx.lineWidth = 2; ctx.beginPath(); ctx.arc(innerWidth/2 + state.x, innerHeight/2 + state.y, 30 + state.scanPulse * 28, 0, Math.PI * 2); ctx.stroke(); if (state.exitVisible) { const exit = layers.find(l => l.type === 'exit'); const sx = innerWidth/2 + exit.x; const sy = innerHeight/2 + exit.y; ctx.strokeStyle = 'rgba(68,209,138,.22)'; ctx.lineWidth = 1.5; ctx.setLineDash([8,10]); ctx.beginPath(); ctx.moveTo(innerWidth/2 + state.x, innerHeight/2 + state.y); ctx.lineTo(sx, sy); ctx.stroke(); ctx.setLineDash([]); } ctx.restore(); } let last = performance.now(); function frame(now){ const dt = Math.min(.033, (now - last) / 1000); last = now; updatePlayer(dt); updateWorld(dt); drawFX(dt); updateHUD(); requestAnimationFrame(frame); } addEventListener('keydown', (e) => { const k = e.key.toLowerCase(); keys.add(k); if (['arrowup','arrowdown','arrowleft','arrowright',' '].includes(k)) e.preventDefault(); if (k === 'shift') state.boost = true; if (k === 't') manipulateTime(); if (k === 'g') alterGravity(); if (k === 'r') rewritePhysics(); if (k === ' ') scanLayer(); }); addEventListener('keyup', (e) => { keys.delete(e.key.toLowerCase()); if (e.key.toLowerCase() === 'shift') state.boost = false; }); addEventListener('pointermove', (e) => { const px = (e.clientX / innerWidth) * 2 - 1; const py = (e.clientY / innerHeight) * 2 - 1; state.tiltY = px * 14; state.tiltX = -py * 10; }, {passive:true}); startBtn.addEventListener('click', startGame); timeBtn.addEventListener('click', manipulateTime); gravityBtn.addEventListener('click', alterGravity); rewriteBtn.addEventListener('click', rewritePhysics); scanBtn.addEventListener('click', scanLayer); resetBtn.addEventListener('click', resetGame); playAgainBtn.addEventListener('click', () => { resetGame(); startGame(); }); closeWinBtn.addEventListener('click', () => winScreen.classList.remove('on')); resetParticles(); resetGame(); requestAnimationFrame(frame); })(); </script> </body> </html>
Save file
Quick jump
open a path
Open