DOOM
lfm2 24b a2b · basic

Browser check: Artifact runtime error · External resource blocked. This is a technical check, not a quality review.
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 6,302 bytes · SHA-256 88b31c86c9f9
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Retro FPS Game</title>
<style>
body { margin: 0; background: #000; display: flex; justify-content: center; align-items: center; height: 100vh; }
canvas { border: 2px solid #fff; background: #111; }
#ui { position: absolute; top: 10px; left: 10px; color: #fff; font-family: Arial, sans-serif; }
</style>
</head>
<body>
<div id="ui">
<div>Health: <span id="health">100</span></div>
<div>Ammo: <span id="ammo">10</span></div>
<div>Weapons: <span id="weapons"></span></div>
<div>Score: <span id="score">0</span></div>
</div>
<canvas id="gameCanvas" width="800" height="600"></canvas>
<script>
const canvas = document.getElementById('gameCanvas');
const ctx = canvas.getContext('2d');
let player = { x: 400, y: 300, radius: 15, speed: 5, angle: 0, ammo: 10, health: 100, score: 0, weapons: [{ name: 'Pistol', ammo: 10 }, { name: 'Shotgun', ammo: 3 }, { name: 'Rifle', ammo: 5 }], currentWeapon: 0 },
enemies = [], bullets = [], pickedup = null, gameOver = false;
const playerImg = new Image(); playerImg.src = 'https://i.imgur.com/7kXZ9yA.png';
player.img = playerImg;
function drawPlayer() {
ctx.save();
ctx.translate(player.x, player.y);
ctx.rotate(player.angle);
ctx.drawImage(player.img, -player.radius, -player.radius, player.radius*2, player.radius*2);
ctx.restore();
}
function drawEnemies() {
enemies.forEach(e => {
ctx.save();
ctx.translate(e.x, e.y);
ctx.drawImage(enemyImg, -e.w/2, -e.h/2, e.w, e.h);
ctx.restore();
});
}
function drawBullets() {
bullets.forEach(b => {
ctx.save();
ctx.translate(b.x, b.y);
ctx.drawImage(bulletImg, -5, -5, 10, 10);
ctx.restore();
});
}
function drawPickups() {
if (pickedup) {
const { type, x, y } = pickedup;
ctx.save();
ctx.translate(x, y);
enemyImg.x = x; enemyImg.y = y;
ctx.drawImage(enemyImg, -enemyImg.width/2, -enemyImg.height/2, enemyImg.width, enemyImg.height);
ctx.restore();
}
}
function drawUI() {
document.getElementById('health').textContent = Math.floor(player.health);
document.getElementById('ammo').textContent = player.ammo;
document.getElementById('weapons').textContent = player.weapons.map(w => w.name).join(', ');
document.getElementById('score').textContent = player.score;
}
function update() {
if (gameOver) return;
ctx.clearRect(0, 0, canvas.width, canvas.height);
drawPlayer();
drawEnemies();
drawBullets();
drawPickups();
drawUI();
// Movement
const keys = { w: false, a: false, s: false, d: false, space: false };
document.addEventListener('keydown', e => {
if (e.code === 'KeyW') keys.w = true;
if (e.code === 'KeyA') keys.a = true;
if (e.code === 'KeyS') keys.s = true;
if (e.code === 'KeyD') keys.d = true;
if (e.code === 'Space') keys.space = true;
});
if (document.keyboardInputs.length) {
const input = document.keyboardInputs[0];
if (input) keys[input.code] = true;
}
if (keys.w) player.y -= player.speed;
if (keys.s) player.y += player.speed;
if (keys.a) player.x -= player.speed;
if (keys.d) player.x += player.speed;
if (keys.space && player.ammo > 0) {
bullets.push({ x: player.x, y: player.y, speed: 10, angle: player.angle });
player.ammo--;
}
// Shooting
bullets.forEach(b => {
b.x += Math.cos(b.angle) * b.speed;
b.y += Math.sin(b.angle) * b.speed;
if (b.x < 0 || b.x > canvas.width || b.y < 0 || b.y > canvas.height) bullets.splice(bullets.indexOf(b), 1);
});
// Enemy AI
enemies.forEach(e => {
e.x += Math.cos(e.angle) * 2;
e.y += Math.sin(e.angle) * 2;
if (Math.hypot(player.x - e.x, player.y - e.y) < 50) {
if (player.ammo > 0 && bullets.length === 0) {
bullets.push({ x: player.x, y: player.y, speed: 10, angle: player.angle });
player.ammo--;
}
e.health -= 20;
if (e.health <= 0) {
enemies.splice(enemies.indexOf(e), 1);
player.score += 50;
}
}
});
// Pickup logic
pickedup = null;
if (Math.hypot(player.x - enemyImg.x, player.y - enemyImg.y) < 15) {
pickedup = { type: 'health', x: enemyImg.x, y: enemyImg.y, health: 20 };
enemies.splice(enemies.indexOf({x: enemyImg.x, y: enemyImg.y}), 1);
}
if (Math.hypot(player.x - playerImg.x, player.y - playerImg.y) < 15 && pickedup === null) {
player.health = Math.min(player.health + 20, 100);
pickedup = { type: 'ammo', x: playerImg.x, y: playerImg.y, ammo: player.ammo + 5 };
}
if (player.health <= 0) {
gameOver = true;
alert('Game Over!');
}
updateUI();
}
function animate() {
update();
requestAnimationFrame(animate);
}
animate();
</script>
</body>
</html>
<!-- agent-meta {"model":"liquid/lfm2-24b-a2b","provider":"lmstudio","persona":"basic","sessionId":"fc049102-beae-4bc5-bada-4aad575b51f7","tokensIn":239,"tokensOut":1633,"tokensTotal":1872,"cost":0,"turns":1,"toolCalls":0,"failedToolCalls":0,"timestamp":"2026-08-01T04:48:31.014Z"} -->