DOOM
GPT 5.6 terra · full

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 11,724 bytes · SHA-256 23305df279c2
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1">
<title>NEON CITADEL // Retro FPS</title>
<style>
html,body{margin:0;height:100%;overflow:hidden;background:#05070d;color:#e7f6ff;font-family:monospace}canvas{width:100vw;height:100vh;display:block;image-rendering:pixelated;cursor:crosshair}#hud{position:fixed;inset:0;pointer-events:none;text-shadow:2px 2px #000;letter-spacing:1px}.top{position:absolute;top:18px;left:22px;font-size:12px;color:#77dfff}.title{font-weight:bold;font-size:16px;color:#fff}.stats{position:absolute;bottom:19px;left:22px;display:flex;gap:17px;align-items:end}.stat b{display:block;font-size:30px;line-height:27px;color:#fff}.stat span{font-size:10px;color:#80c5d7}.ammo b{color:#ffd665}.health b{color:#75f7a0}.weapon{position:absolute;bottom:20px;right:24px;text-align:right}.weapon b{font-size:18px;color:#f36a9d}.weapon span{font-size:10px;color:#d0a9bc}.bar{width:150px;height:7px;border:1px solid #72bdcf;margin-top:5px;background:#13202a}.bar i{display:block;height:100%;background:#45e5c4}.tip{position:absolute;bottom:80px;left:50%;transform:translateX(-50%);font-size:11px;color:#9dbac7;text-align:center}.flash{position:absolute;inset:0;background:#fff;opacity:0;mix-blend-mode:overlay}.center{position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);text-align:center;background:#071019e8;border:2px solid #63d8ef;padding:28px 36px;display:none;min-width:350px}.center h1{margin:0 0 10px;color:#ff6b9b;font-size:29px}.center p{color:#b9d9e1;line-height:1.5}.center strong{color:#fff}.cross{position:absolute;left:50%;top:50%;width:17px;height:17px;transform:translate(-50%,-50%)}.cross:before,.cross:after{content:'';position:absolute;background:#d4fbff;box-shadow:0 0 5px #70e7ff}.cross:before{width:17px;height:1px;top:8px}.cross:after{height:17px;width:1px;left:8px}
</style></head><body>
<canvas id="game" width="480" height="270"></canvas>
<div id="hud"><div class="top"><div class="title">NEON CITADEL</div><div id="objective">PURGE THE CORE GUARDIANS // 0 REMAIN</div></div><div class="cross"></div><div class="stats"><div class="stat health"><b id="hp">100</b><span>VITALITY</span></div><div class="stat ammo"><b id="ammo">48</b><span id="ammoType">CELL CHARGES</span></div><div class="stat"><b id="kills">0/0</b><span>HOSTILES</span></div></div><div class="weapon"><b id="weapon">PULSE RIFLE</b><span id="wepdesc">[1] PULSE [2] SCATTER [3] ARC</span><div class="bar"><i id="weaponbar" style="width:100%"></i></div></div><div class="tip" id="tip">CLICK TO ENTER THE CITADEL<br>WASD MOVE · MOUSE LOOK · CLICK FIRE · 1–3 SWITCH</div><div class="flash" id="flash"></div><div class="center" id="modal"></div></div>
<script>
(()=>{'use strict';
const c=document.getElementById('game'),x=c.getContext('2d'),W=480,H=270; x.imageSmoothingEnabled=false;
const ui={hp:document.getElementById('hp'),ammo:document.getElementById('ammo'),kills:document.getElementById('kills'),weapon:document.getElementById('weapon'),ammoType:document.getElementById('ammoType'),objective:document.getElementById('objective'),tip:document.getElementById('tip'),modal:document.getElementById('modal'),flash:document.getElementById('flash'),bar:document.getElementById('weaponbar')};
const map=[
'111111111111111','1.............1','1..22...2..3..1','1..2....2.....1','1......22..2..1','1.111...2..2..1','1...1......2..1','1...1.222..2..1','1...1..........1','1......2222....1','1..3...........1','111111111111111'];
const MW=15,MH=12; let P={x:2.5,y:2.5,a:0,hp:100},keys={},locked=false,last=0,shake=0,flash=0,state='play',score=0;
const weapons=[{name:'PULSE RIFLE',ammo:'CELL CHARGES',damage:22,rate:180,spread:.035,color:'#5ff1ff',cost:1},{name:'SCATTER CANNON',ammo:'SHELLS',damage:13,rate:620,spread:.24,color:'#ffc658',cost:1,pellets:7},{name:'ARC PROJECTOR',ammo:'ARC CELLS',damage:65,rate:780,spread:.015,color:'#d778ff',cost:3}]; let wi=0,ammoBag=[50,14,12],cool=0,fireVis=0;
let enemies=[],pickups=[],particles=[];
function init(){P={x:2.5,y:2.5,a:0,hp:100};wi=0;ammoBag=[50,14,12];score=0;state='play';enemies=[
{x:11.5,y:2.5,hp:55,max:55,type:'drone',speed:1.0,cd:1},{x:7.5,y:4.5,hp:55,max:55,type:'drone',speed:.9,cd:0},{x:12.3,y:6.7,hp:80,max:80,type:'guard',speed:.65,cd:2},{x:2.3,y:8.5,hp:80,max:80,type:'guard',speed:.62,cd:1},{x:10.5,y:9.4,hp:80,max:80,type:'guard',speed:.68,cd:2},{x:12.2,y:10.2,hp:180,max:180,type:'core',speed:.42,cd:1.4}]; pickups=[{x:5.4,y:2.5,k:'health'},{x:9.5,y:3.5,k:'ammo'},{x:6.4,y:6.5,k:'shell'},{x:3.2,y:10.1,k:'health'},{x:9.4,y:10.3,k:'arc'}];particles=[];ui.modal.style.display='none';updateUI()}
function wall(px,py){let X=Math.floor(px),Y=Math.floor(py);return X<0||Y<0||X>=MW||Y>=MH||map[Y][X]!==' .'.trim()&&map[Y][X]!=='.'}
function move(dx,dy){let r=.18;if(!wall(P.x+dx+r*Math.sign(dx),P.y))P.x+=dx;if(!wall(P.x,P.y+dy+r*Math.sign(dy)))P.y+=dy}
function updateUI(){let w=weapons[wi];ui.hp.textContent=Math.max(0,Math.ceil(P.hp));ui.ammo.textContent=ammoBag[wi];ui.ammoType.textContent=w.ammo;ui.weapon.textContent=w.name;ui.kills.textContent=score+'/'+enemies.length;ui.objective.textContent=enemies.length?'PURGE THE CORE GUARDIANS // '+enemies.length+' REMAIN':'CITADEL CORE NEUTRALIZED';ui.bar.style.width=Math.max(0,100-cool/w.rate*100)+'%'}
function fire(){if(state!=='play'||cool>0||ammoBag[wi]<weapons[wi].cost)return;let w=weapons[wi];ammoBag[wi]-=w.cost;cool=w.rate;fireVis=.12;flash=.15;shake=3; for(let q=0;q<(w.pellets||1);q++){let a=P.a+(Math.random()-.5)*w.spread;let hit=null,dist=99;for(let e of enemies){let dx=e.x-P.x,dy=e.y-P.y,d=Math.hypot(dx,dy),diff=Math.abs(Math.atan2(Math.sin(Math.atan2(dy,dx)-a),Math.cos(Math.atan2(dy,dx)-a)));if(diff<.11/d*1.8&&d<dist&&clear(P.x,P.y,e.x,e.y)){hit=e;dist=d}}if(hit){let dmg=w.damage*(.85+Math.random()*.3);hit.hp-=dmg;burst(hit.x,hit.y,w.color);if(hit.hp<=0){enemies=enemies.filter(e=>e!==hit);score++;burst(hit.x,hit.y,'#ff5577',24)}}}updateUI()}
function clear(ax,ay,bx,by){let d=Math.hypot(bx-ax,by-ay),n=Math.ceil(d*8);for(let i=1;i<n;i++)if(wall(ax+(bx-ax)*i/n,ay+(by-ay)*i/n))return false;return true}
function burst(px,py,col,n=10){for(let i=0;i<n;i++)particles.push({x:px,y:py,vx:(Math.random()-.5)*3,vy:(Math.random()-.5)*3,z:Math.random()*.5+.25,t:.3+Math.random()*.4,col})}
function damage(v){P.hp-=v;flash=.35;shake=7;if(P.hp<=0){state='dead';locked=false;document.exitPointerLock();ui.modal.innerHTML='<h1>SYSTEM FAILURE</h1><p>You were recycled by the Citadel.</p><p><strong>CLICK TO RESPAWN</strong></p>';ui.modal.style.display='block'}updateUI()}
function update(dt){if(state!=='play')return;let speed=(keys.Shift?3.3:2.15)*dt;if(keys.w||keys.ArrowUp)move(Math.cos(P.a)*speed,Math.sin(P.a)*speed);if(keys.s||keys.ArrowDown)move(-Math.cos(P.a)*speed,-Math.sin(P.a)*speed);if(keys.a)move(Math.cos(P.a-Math.PI/2)*speed,Math.sin(P.a-Math.PI/2)*speed);if(keys.d)move(Math.cos(P.a+Math.PI/2)*speed,Math.sin(P.a+Math.PI/2)*speed);cool=Math.max(0,cool-dt*1000);fireVis=Math.max(0,fireVis-dt);flash=Math.max(0,flash-dt);shake=Math.max(0,shake-dt*20);
for(let e of enemies){let dx=P.x-e.x,dy=P.y-e.y,d=Math.hypot(dx,dy);e.cd-=dt;if(d<7&&clear(e.x,e.y,P.x,P.y)){if(d>1.9){let vx=dx/d*e.speed*dt,vy=dy/d*e.speed*dt;if(!wall(e.x+vx,e.y))e.x+=vx;if(!wall(e.x,e.y+vy))e.y+=vy}if(e.cd<0){damage(e.type==='core'?15:e.type==='guard'?9:6);e.cd=e.type==='core'?1.0:1.35;burst(P.x,P.y,'#ff334f',5)}}}
pickups=pickups.filter(o=>{if(Math.hypot(o.x-P.x,o.y-P.y)<.48){if(o.k==='health')P.hp=Math.min(100,P.hp+35);else if(o.k==='ammo')ammoBag[0]+=28;else if(o.k==='shell')ammoBag[1]+=8;else ammoBag[2]+=5;burst(o.x,o.y,'#74ffc6',16);return false}return true});particles=particles.filter(p=>{p.x+=p.vx*dt;p.y+=p.vy*dt;p.t-=dt;return p.t>0});if(!enemies.length){state='win';locked=false;document.exitPointerLock();ui.modal.innerHTML='<h1>CITADEL PURGED</h1><p>The core is silent. Your score: <strong>'+score+' guardians</strong></p><p><strong>CLICK TO RUN IT AGAIN</strong></p>';ui.modal.style.display='block'}updateUI()}
function render(){// sky/floor
x.fillStyle='#091226';x.fillRect(0,0,W,H/2);x.fillStyle='#101018';x.fillRect(0,H/2,W,H/2); for(let yy=H/2;yy<H;yy+=3){x.fillStyle=`rgba(45,50,77,${(yy-H/2)/H*.42})`;x.fillRect(0,yy,W,1)}
let zbuf=[];let fov=Math.PI/3;for(let col=0;col<W;col+=2){let ra=P.a-fov/2+col/W*fov,rx=Math.cos(ra),ry=Math.sin(ra),d=0;while(d<20){d+=.025;if(wall(P.x+rx*d,P.y+ry*d))break}let cd=d*Math.cos(ra-P.a),h=Math.min(H*1.8,H/cd),top=H/2-h/2;zbuf[col]=cd;let side=Math.abs((P.x+rx*d)%1)<.04||Math.abs((P.y+ry*d)%1)<.04;let shade=Math.max(18,170-cd*16)*(side?.7:1);let tile=map[Math.floor(P.y+ry*d)]?.[Math.floor(P.x+rx*d)]||'1';let base=tile==='2'?[40,120,145]:tile==='3'?[112,48,122]:[40,76,99];x.fillStyle=`rgb(${base.map(v=>v*shade/170|0).join(',')})`;x.fillRect(col,top,2,h);if(h>16){x.fillStyle='rgba(130,240,255,.18)';x.fillRect(col,top+(Math.sin(d*15)*2|0),2,1)}}
// sprites
let things=[...pickups.map(o=>({...o,kind:'pick'})),...enemies.map(e=>({...e,kind:'enemy'})),...particles.map(p=>({...p,kind:'part'}))].sort((a,b)=>Math.hypot(b.x-P.x,b.y-P.y)-Math.hypot(a.x-P.x,a.y-P.y));
for(let o of things){let dx=o.x-P.x,dy=o.y-P.y,d=Math.hypot(dx,dy),a=Math.atan2(dy,dx)-P.a;a=Math.atan2(Math.sin(a),Math.cos(a));if(Math.abs(a)>fov*.65||d<.1)continue;let sx=W/2+(a/fov)*W,zi=zbuf[Math.max(0,Math.min(W-2,(sx|0)&~1))]||99;if(d>zi+.25)continue;if(o.kind==='part'){let s=Math.max(1,6/d);x.fillStyle=o.col;x.fillRect(sx-s/2,H/2-s/2,s,s);continue}let s=(o.kind==='enemy'?(o.type==='core'?90:54):30)/d,sy=H/2-s/2;if(o.kind==='pick'){x.fillStyle=o.k==='health'?'#48f09b':o.k==='shell'?'#ffbf57':o.k==='arc'?'#c468ff':'#5fdcff';x.fillRect(sx-s/2,sy,s,s);x.fillStyle='#dfffff';x.fillRect(sx-s*.2,sy+s*.18,s*.4,s*.4)}else{let col=o.type==='core'?'#d24778':o.type==='guard'?'#e39344':'#e84765';x.fillStyle='rgba(0,0,0,.4)';x.fillRect(sx-s*.42,sy+s*.08,s*.84,s*.9);x.fillStyle=col;x.fillRect(sx-s*.38,sy+s*.2,s*.76,s*.62);x.fillStyle='#1a0f1b';x.fillRect(sx-s*.23,sy+s*.37,s*.46,s*.13);x.fillStyle='#ffeff4';x.fillRect(sx-s*.15,sy+s*.32,s*.1,s*.08);x.fillRect(sx+s*.06,sy+s*.32,s*.1,s*.08);x.fillStyle='#6effff';x.fillRect(sx-s*.42,sy+s*.95,s*.84*(o.hp/o.max),3)}}
// weapon
let w=weapons[wi];let bob=Math.sin(performance.now()/100)*2;x.fillStyle='#101b29';x.fillRect(W*.37,H-42+bob,W*.26,42);x.fillStyle=w.color;x.fillRect(W*.46,H-58+bob+(fireVis?5:0),W*.09,45);x.fillStyle='#dbeeff';x.fillRect(W*.485,H-66+bob,W*.04,20);if(fireVis){x.fillStyle=w.color;x.globalAlpha=fireVis*4;x.fillRect(W*.38,H-100,W*.24,55);x.globalAlpha=1}if(shake){x.fillStyle='rgba(255,55,72,.12)';x.fillRect(0,0,W,H)}ui.flash.style.opacity=flash;
}
function loop(t){let dt=Math.min(.04,(t-last)/1000||0);last=t;update(dt);render();requestAnimationFrame(loop)}
addEventListener('keydown',e=>{keys[e.key]=true;if(['1','2','3'].includes(e.key)){wi=+e.key-1;updateUI()}if(e.key===' '){e.preventDefault();fire()}});addEventListener('keyup',e=>keys[e.key]=false);c.addEventListener('click',()=>{if(state!=='play'){init();state='play'}c.requestPointerLock()});document.addEventListener('pointerlockchange',()=>{locked=document.pointerLockElement===c;ui.tip.style.display=locked?'none':'block'});document.addEventListener('mousemove',e=>{if(locked&&state==='play')P.a+=e.movementX*.0025});document.addEventListener('mousedown',e=>{if(locked&&e.button===0)fire()});
init();requestAnimationFrame(loop);
})();
</script></body></html>
<!-- agent-meta {"model":"openai/gpt-5.6-terra","provider":"openrouter","persona":"full","sessionId":"ca1c3ca5-7059-48cd-ab30-7e5626cc69aa","tokensIn":51112,"tokensOut":4981,"tokensTotal":56093,"turns":8,"toolCalls":7,"failedToolCalls":0,"timestamp":"2026-07-31T19:18:10.493Z"} -->