← RPG results

RPG

GPT 5.6 Luna Pro · composer

Initial view of RPG

Reviews & generation details

Reviews

No human review yet. Unreviewed does not mean unsuccessful.

Generation context

Imported historical artifact. Its exact original instructions and lineage are not known.

Generation prompt · exact text unavailable

See the current prompt for reference. It may differ from the instructions used to generate this artifact.

Inspect original source 14,203 bytes · SHA-256 80bae0d7698d
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Emberwake: The Lantern Depths</title>
<style>
/* ── css: base ── */
@import url('https://fonts.googleapis.com/css2?family=DM+Mono:wght@400;500&family=Unbounded:wght@400;600;700&display=swap');
:root{--ink:#eef4e7;--muted:#9aab9b;--gold:#f4b85d;--ember:#ef6a4d;--teal:#74d4bc;--panel:#111b1d}*{box-sizing:border-box}body{margin:0;background:#081012;color:var(--ink);font-family:'DM Mono',monospace;overflow:hidden}#game{position:relative;width:100vw;height:100vh;min-height:650px;display:grid;place-items:center;background:radial-gradient(circle at 50% 40%,#183538 0,#081012 67%)}canvas{width:min(1100px,100vw);height:min(650px,100vh);image-rendering:auto;box-shadow:0 0 80px #020708;border:1px solid #385454}#hud{position:fixed;inset:0;pointer-events:none;padding:22px max(24px,calc((100vw - 1100px)/2 + 24px));display:flex;align-items:flex-start;justify-content:space-between}.brand{display:flex;flex-direction:column;gap:5px}.brand b{font:600 16px 'Unbounded';letter-spacing:2px;color:var(--gold)}.brand span,.eyebrow{font-size:10px;letter-spacing:3px;color:var(--muted)}.stats{display:flex;align-items:center;gap:18px}.hearts{color:var(--ember);font-size:23px;letter-spacing:3px;text-shadow:0 0 12px #e85242}.meter{display:flex;flex-direction:column;gap:5px;color:var(--muted);font-size:9px}.meter i{display:block;width:100px;height:5px;border-radius:5px;background:#263537;overflow:hidden}.meter i:after{content:'';display:block;height:100%;width:75%;background:var(--teal);border-radius:5px}.coins{font-size:16px;color:var(--gold);background:#0c1719cc;padding:9px 12px;border:1px solid #385454;border-radius:4px}.equip{position:absolute;left:max(24px,calc((100vw - 1100px)/2 + 24px));bottom:26px;display:flex;flex-direction:column;gap:4px}.equip span{font:600 12px 'Unbounded';color:var(--teal);letter-spacing:1px}.equip small{font-size:10px;color:var(--muted)}.inventory{position:absolute;right:max(24px,calc((100vw - 1100px)/2 + 24px));bottom:25px;display:flex;gap:6px}.slot{width:40px;height:40px;border:1px solid #416061;background:#0c1719d9;display:grid;place-items:center;font-size:18px;border-radius:3px}.slot small{font-size:8px;color:var(--muted)}.hint{position:absolute;bottom:82px;left:50%;transform:translateX(-50%);font-size:10px;color:#78908d;background:#0b1517bb;padding:7px 12px;border-radius:3px}.panel,.screen{position:fixed;inset:50% auto auto 50%;transform:translate(-50%,-50%);background:linear-gradient(145deg,#142628f5,#0b1416f5);border:1px solid #4d7775;box-shadow:0 20px 70px #000b;padding:30px;width:min(440px,90vw);z-index:3}.hidden{display:none}.panel h2{font:600 18px 'Unbounded';margin:0 0 20px;color:var(--gold)}#closePanel{position:absolute;right:14px;top:10px;border:0;background:none;color:var(--muted);font-size:24px;cursor:pointer}.shopRow{display:flex;justify-content:space-between;align-items:center;border-top:1px solid #294144;padding:14px 0}.shopRow b{color:var(--teal)}button{background:var(--gold);border:0;color:#101719;padding:12px 18px;font:500 11px 'DM Mono';letter-spacing:1px;cursor:pointer}button:hover{background:#ffd383}.screen{text-align:center;width:470px;padding:48px 42px}.screen h1{font:700 38px 'Unbounded';letter-spacing:2px;margin:10px 0;color:var(--gold)}.screen p:not(.eyebrow){color:#b6c7b9;line-height:1.7;font-size:13px}.screen small{display:block;color:#6e8782;font-size:10px;margin-top:20px}.sigil{font-size:45px;color:var(--ember);text-shadow:0 0 25px #ef6a4d}.toast{position:fixed;top:120px;left:50%;transform:translateX(-50%) translateY(-10px);background:#e6b15a;color:#101719;padding:10px 18px;font-size:11px;opacity:0;transition:.25s;z-index:5}.toast.on{opacity:1;transform:translateX(-50%) translateY(0)}
/* ── css: mobile ── */
@media(max-width:700px){#hud{padding:14px}.brand span{display:none}.stats{gap:8px}.meter{display:none}.coins{font-size:12px;padding:7px}.hint{bottom:72px;font-size:8px;white-space:nowrap}.equip{left:14px;bottom:18px}.inventory{right:14px;bottom:15px}.slot{width:32px;height:32px;font-size:15px}.screen{padding:34px 20px}.screen h1{font-size:27px}}
</style>
</head>
<body>
<main id="game"><canvas id="world" width="1100" height="650"></canvas><section id="hud"><div class="brand"><b>EMBERWAKE</b><span>THE LANTERN DEPTHS</span></div><div class="stats"><div id="hearts" class="hearts"></div><div class="meter"><span>STAMINA</span><i id="stamina"></i></div><div class="coins">◈ <strong id="gold">0</strong></div></div><div class="equip"><span id="weapon">RUSTED SABER</span><small id="weaponDetail">slash · 1 dmg</small></div><div id="inventory" class="inventory"></div><div class="hint" id="hint">WASD / ARROWS move · SPACE attack · E interact</div></section><aside id="panel" class="panel hidden"><button id="closePanel">×</button><h2 id="panelTitle">FIELD SATCHEL</h2><div id="panelBody"></div></aside><div id="toast"></div><div id="startScreen" class="screen"><div class="sigil">✦</div><p class="eyebrow">A SMALL ADVENTURE</p><h1>EMBERWAKE</h1><p>Descend into the old lantern mines. Find the relics. Bring the light home.</p><button id="startBtn">BEGIN EXPEDITION</button><small>best played with sound</small></div></main>
<script>
'use strict';

// ── const: G ──
const G={x:130,y:430,hp:6,maxHp:6,gold:18,stam:100,weapon:0,items:[],upgrade1:false,upgrade2:false,bow:false,progress:0,save:{x:130,y:430},attack:0,invuln:0,toast:0,started:false,dead:false};

// ── const: keys ──
const keys={};

// ── function: say ──
function say(t){G.toast=t;const el=document.querySelector('#toast');el.textContent=t;el.classList.add('on');clearTimeout(window._toast);window._toast=setTimeout(()=>el.classList.remove('on'),2200)}

// ── function: sfx ──
function sfx(type){try{const a=new AudioContext(),o=a.createOscillator(),v=a.createGain();o.type=type==='hit'?'sawtooth':'sine';o.frequency.value=type==='hit'?110:type==='pickup'?660:type==='hurt'?90:240;v.gain.value=.035;o.connect(v);v.connect(a.destination);o.start();v.gain.exponentialRampToValueAtTime(.001,a.currentTime+.12);o.stop(a.currentTime+.13)}catch(e){}}

// ── function: hearts ──
function hearts(){let s='';for(let i=0;i<G.maxHp/2;i++)s+=i*2<G.hp?'♥':'♡';document.querySelector('#hearts').textContent=s;document.querySelector('#gold').textContent=G.gold;document.querySelector('#weapon').textContent=G.bow?'EMBER BOW':G.weapon===2?'MOONFORGED EDGE':G.weapon===1?'BRONZE CLEAVER':'RUSTED SABER';document.querySelector('#weaponDetail').textContent=G.bow?'ranged · 2 dmg':G.weapon===2?'arcane slash · 3 dmg':G.weapon===1?'heavy cleave · 2 dmg':'slash · 1 dmg';document.querySelector('#stamina').style.setProperty('--x',G.stam+'%');document.querySelector('#inventory').innerHTML=G.items.map(i=>`<div class="slot" title="${i.name}">${i.icon}</div>`).join('')}

// ── function: addItem ──
function addItem(name,icon){if(!G.items.some(x=>x.name===name)){G.items.push({name,icon});say('FOUND: '+name);sfx('pickup');hearts();return true}return false}

// ── function: makeWorld ──
function makeWorld(){const c=document.querySelector('#world'),ctx=c.getContext('2d');return {c,ctx,particles:[],enemies:[{x:520,y:260,hp:4,max:4,kind:'warden',alive:true},{x:835,y:430,hp:5,max:5,kind:'moth',alive:true},{x:680,y:145,hp:3,max:3,kind:'moth',alive:true}],pickups:[{x:275,y:145,n:'Sunshard',i:'✦',got:false},{x:425,y:505,n:'Gilded Root',i:'❈',got:false},{x:790,y:170,n:'Moon Sigil',i:'◉',got:false},{x:948,y:330,n:'Heart Vessel',i:'♥',got:false}],shots:[]}}

// ── function: particle ──
function particle(w,x,y,col='#f4b85d',n=12){for(let i=0;i<n;i++)w.particles.push({x,y,vx:(Math.random()-.5)*3,vy:(Math.random()-.5)*3,life:35,col})}

// ── function: draw ──
function draw(w){const {ctx:c}=w;c.clearRect(0,0,1100,650);c.fillStyle='#102527';c.fillRect(0,0,1100,650);c.fillStyle='#183537';for(let x=0;x<1100;x+=44)for(let y=0;y<650;y+=44){c.fillRect(x+1,y+1,40,40)}c.strokeStyle='#345a58';c.lineWidth=2;c.strokeRect(24,25,1052,600);c.fillStyle='#0a1517';c.fillRect(63,72,185,105);c.fillRect(385,72,250,105);c.fillRect(755,72,278,105);c.fillRect(67,365,170,190);c.fillRect(344,350,190,205);c.fillRect(720,345,300,210);c.fillStyle='#25494a';c.fillRect(250,120,135,28);c.fillRect(635,122,120,25);c.fillRect(532,390,188,25);c.fillStyle='#d6a04e';c.beginPath();c.arc(128,96,13,0,7);c.fill();c.fillStyle='#6ac8b1';c.beginPath();c.arc(315,260,15,0,7);c.fill();c.fillStyle='#b66d4e';c.fillRect(930,260,30,34);c.fillStyle='#91aaa2';c.font='11px DM Mono';c.fillText('CAMP',104,120);c.fillText('ANCIENT GATE',414,120);c.fillText('TRADER',910,225);c.fillStyle='#52706d';c.font='10px DM Mono';c.fillText('THE DROWNED QUARRY',400,610);c.fillText('SUNLIT CAVES',70,330);c.fillText('✧  E  SAVE',92,145);c.fillText('E  SHOP',900,250);w.pickups.forEach(p=>{if(!p.got){c.shadowBlur=18;c.shadowColor='#f4b85d';c.fillStyle='#f4b85d';c.font='24px serif';c.fillText(p.i,p.x-8,p.y+8);c.shadowBlur=0}});w.enemies.forEach(e=>{if(!e.alive)return;c.fillStyle=e.kind==='warden'?'#b65e56':'#845c9c';c.beginPath();c.arc(e.x,e.y,18,0,7);c.fill();c.fillStyle='#edc56d';c.fillRect(e.x-15,e.y-28,30*(e.hp/e.max),3);c.fillStyle='#f5d9a0';c.beginPath();c.arc(e.x-5,e.y-3,3,0,7);c.fill();});w.shots.forEach(s=>{c.fillStyle='#f4b85d';c.beginPath();c.arc(s.x,s.y,5,0,7);c.fill()});c.save();c.translate(G.x,G.y);c.fillStyle=G.invuln>0?'#ffffff':'#74d4bc';c.beginPath();c.arc(0,0,15,0,7);c.fill();c.fillStyle='#132224';c.fillRect(-9,-8,18,5);c.strokeStyle=G.bow?'#f4b85d':'#d8e3cc';c.lineWidth=4;c.beginPath();c.moveTo(9,-5);c.lineTo(G.bow?18:26,G.bow?10:-15);c.stroke();c.restore();w.particles.forEach(p=>{c.fillStyle=p.col;c.globalAlpha=p.life/35;c.fillRect(p.x,p.y,3,3);c.globalAlpha=1});}

// ── function: update ──
function update(w){if(!G.started||G.dead)return;let dx=(keys.ArrowRight||keys.d?1:0)-(keys.ArrowLeft||keys.a?1:0),dy=(keys.ArrowDown||keys.s?1:0)-(keys.ArrowUp||keys.w?1:0);let sp=G.stam>0?2.8:1.3;if(dx||dy){let l=Math.hypot(dx,dy);G.x+=dx/l*sp;G.y+=dy/l*sp;G.stam=Math.max(0,G.stam-.3)}else G.stam=Math.min(100,G.stam+.7);G.x=Math.max(42,Math.min(1055,G.x));G.y=Math.max(45,Math.min(600,G.y));G.invuln=Math.max(0,G.invuln-1);G.attack=Math.max(0,G.attack-1);w.shots.forEach(s=>{s.x+=s.vx;s.y+=s.vy;w.enemies.forEach(e=>{if(e.alive&&Math.hypot(s.x-e.x,s.y-e.y)<22){e.hp-=2;s.dead=true;particle(w,e.x,e.y,'#f4b85d',10);if(e.hp<=0){e.alive=false;G.gold+=8;say('WARDEN FALLS · +8 ◈');hearts()}}})});w.shots=w.shots.filter(s=>!s.dead&&s.x>0&&s.x<1100);w.enemies.forEach(e=>{if(!e.alive)return;if(Math.hypot(G.x-e.x,G.y-e.y)<30&&G.invuln<=0){G.hp-=1;G.invuln=55;particle(w,G.x,G.y,'#ef6a4d',14);say('HIT!');sfx('hurt');hearts();if(G.hp<=0){G.dead=true;say('YOU FADE… RETURNING TO CAMP');setTimeout(()=>{G.dead=false;G.hp=G.maxHp;G.x=G.save.x;G.y=G.save.y;hearts()},1800)}}});w.pickups.forEach(p=>{if(!p.got&&Math.hypot(G.x-p.x,G.y-p.y)<28){p.got=true;G.gold+=10;addItem(p.n,p.i);G.progress++;if(p.n==='Heart Vessel'){G.maxHp=10;G.hp=10;say('HEART VESSEL · 5 CONTAINERS');hearts()}if(G.progress===2){G.bow=true;say('MIDPOINT DISCOVERY · EMBER BOW');hearts()}if(G.progress===3&&G.weapon===0){G.weapon=1;say('UPGRADE UNLOCKED · BRONZE CLEAVER');hearts()}if(G.progress===4){G.weapon=2;say('UPGRADE UNLOCKED · MOONFORGED EDGE');hearts()}}});w.particles.forEach(p=>{p.x+=p.vx;p.y+=p.vy;p.life--});w.particles=w.particles.filter(p=>p.life>0);}

// ── function: attack ──
function attack(w){if(!G.started||G.attack>0)return;G.attack=18;sfx('hit');particle(w,G.x+(keys.ArrowLeft?-20:20),G.y,G.bow?'#f4b85d':'#74d4bc',7);if(G.bow){w.shots.push({x:G.x,y:G.y,vx:keys.ArrowLeft?-7:7,vy:0})}else w.enemies.forEach(e=>{if(e.alive&&Math.hypot(G.x-e.x,G.y-e.y)<62){e.hp-=G.weapon===2?3:G.weapon===1?2:1;if(e.hp<=0){e.alive=false;G.gold+=8;say('ENEMY DEFEATED · +8 ◈');hearts()}particle(w,e.x,e.y,'#ef6a4d',14)}})}

// ── function: interact ──
function interact(w){let d=Math.hypot(G.x-128,G.y-96),shop=Math.hypot(G.x-945,G.y-277);if(d<55){G.save={x:130,y:125};say('CAMPFIRE MARKED · PROGRESS SAVED');particle(w,128,96,'#74d4bc',18);sfx('pickup')}else if(shop<70){openShop()}}

// ── function: openShop ──
function openShop(){document.querySelector('#panel').classList.remove('hidden');document.querySelector('#panelBody').innerHTML='<p style="color:#9aab9b;font-size:12px;line-height:1.6">The trader deals in small advantages. Choose wisely.</p><div class="shopRow"><span><b>HEART TONIC</b><br><small>restore 2 health</small></span><button data-buy="tonic">8 ◈</button></div><div class="shopRow"><span><b>LUCKY CHARM</b><br><small>carry a charm</small></span><button data-buy="charm">12 ◈</button></div>';document.querySelectorAll('[data-buy]').forEach(b=>b.onclick=()=>{if(G.gold<+b.textContent.split(' ')[0])return say('NOT ENOUGH COIN');G.gold-=+b.textContent.split(' ')[0];addItem(b.dataset.buy==='tonic'?'Heart Tonic':'Lucky Charm',b.dataset.buy==='tonic'?'♧':'✥');if(b.dataset.buy==='tonic')G.hp=Math.min(G.maxHp,G.hp+2);hearts();sfx('pickup')})}

// ── function: loop ──
function loop(w){update(w);draw(w);requestAnimationFrame(()=>loop(w))}

// ── main ──
const w=makeWorld();hearts();document.querySelector('#startBtn').onclick=()=>{G.started=true;document.querySelector('#startScreen').classList.add('hidden');say('THE DEPTHS AWAIT');sfx('pickup')};document.querySelector('#closePanel').onclick=()=>document.querySelector('#panel').classList.add('hidden');window.addEventListener('keydown',e=>{keys[e.key]=true;if(e.key===' '){e.preventDefault();attack(w)}if(e.key.toLowerCase()==='e')interact(w);if(e.key.toLowerCase()==='i')document.querySelector('#panel').classList.toggle('hidden')});window.addEventListener('keyup',e=>keys[e.key]=false);loop(w);
</script>
</body>
</html>
<!-- agent-meta {"model":"openai/gpt-5.6-luna-pro","provider":"openrouter","persona":"composer","sessionId":"7e687c68-7cc1-465c-8a1c-dedabd4c30ea","tokensIn":185062,"tokensOut":15981,"tokensTotal":201043,"turns":7,"toolCalls":9,"failedToolCalls":0,"timestamp":"2026-07-30T23:31:43.927Z"} -->