oneshotlm
Compare all models on this prompt →

Dangerous Dave platformer · gpt-oss-120b

Build a playable tile-based platformer on a canvas in the Dangerous Dave style: navigate a level to grab a trophy and then reach the exit, avoiding hazards like fire and water, with jumping and simple enemies. Procedural graphics only, no external assets.

⚠ no runnable output

This one-shot run produced no runnable artifact.

agent produced no index.html

The transcript below shows what the model did — read it to see why the one shot fell short.

transcript · 2 messages
user

Build a playable tile-based platformer on a canvas in the Dangerous Dave style: navigate a level to grab a trophy and then reach the exit, avoiding hazards like fire and water, with jumping and simple enemies. Procedural graphics only, no external assets.

assistant
thinking
We need to create a single file index.html with a canvas game. Should be self-contained, no external resources. We need to implement tile-based platformer: level layout, player movement, gravity, jumping, hazards, enemies, trophy, exit. Procedural graphics (simple shapes). Use JavaScript. Use key events. Provide minimal but functional.

We'll write HTML with a canvas, script that defines level as array of strings, each char representing tile: e.g., '.' empty, '#' solid ground, 'F' fire (hazard), 'W' water (hazard), 'E' enemy, 'T' trophy, 'X' exit. Player starts at some position.

Implement simple physics: gravity, velocity, collision detection with solid tiles.

Enemies: simple moving back and forth.

When player reaches trophy, set flag. When reaches exit after trophy, show win.

Implement minimal UI messages.

We need to write index.html.

Will produce final answer with file content.

**`index.html`** ```html <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Tile‑Based Platformer</title> <style> html,body{margin:0;height:100%;overflow:hidden;background:#222;color:#fff;font-family:sans-serif} #info{position:absolute;top:0;left:0;padding:0.5rem;z-index:2} canvas{background:#000;display:block;margin:auto} </style> </head> <body> <div id="info">← → = jump | Collect trophy (T) → exit (X)</div> <canvas id="game"></canvas> <script> /* ---------- SETTINGS ---------- */ const TILE = 32; // size of a tile (px) const FPS = 60; const GRAVITY = 0.5; const JUMP_SPEED = -8; const PLAYER_SPEED = 2.5; const ENEMY_SPEED = 1.2; /* ---------- LEVEL ---------- */ const level = [ "##############################", "#..............E.............#", "#..............#.............#", "#..T...........#......F......#", "#...........#######...........#", "#...........#.....#...........#", "#...........#.....#...........#", "#...........#.....#...........#", "#...........#.....#...........#", "#...........#.....#...........#", "#...........#.....#...........#", "#...........#.....#...........#", "#...........#.....#...........#", "#...........#####.#...........#", "#..................#...........#", "#..................#...........#", "#..............W...#...........#", "#..................#...........#", "#..................#...........#", "#..................#...........#", "#..................#######.....#", "#.........................X....#", "#......................#######.#", "#...........##########........#", "#...........#..................#", "#...........#..................#", "#...........#.................#", "#...........#.................#", "#...........##################", "#..............................", "#..............................", "#..............................", "#...........###################", "#...........#.................#", "#...........#.................#", "#...........#.................#", "#...........#.................#", "##############################" ]; /* Legend: # = solid wall . = empty F = fire (danger) W = water (danger) E = enemy (patrol) T = trophy (collect) X = exit (requires trophy) */ const rows = level.length; const cols = level[0].length; const width = cols * TILE; const height = rows * TILE; /* ---------- CANVAS ---------- */ const canvas = document.getElementById('game'); canvas.width = width; canvas.height = height; const ctx = canvas.getContext('2d'); /* ---------- PLAYER ---------- */ const player = { x: TILE + 2, y: height - 3 * TILE, w: TILE * 0.8, h: TILE * 0.9, vx: 0, vy: 0, onGround: false, hasTrophy: false }; /* ---------- ENEMIES ---------- */ class Enemy { constructor(x, y) { this.x = x; this.y = y; this.w = TILE * 0.8; this.h = TILE * 0.9; this.vx = ENEMY_SPEED; this.dir = 1; // 1 = right, -1 = left } update() { // Simple left‑right patrol: reverse when hitting solid tile const nextX = this.x + this.dir * ENEMY_SPEED; if (isSolidAt(nextX, this.y) || isSolidAt(nextX + this.w, this.y + this.h)) { this.dir *= -1; } this.x += this.dir * ENEMY_SPEED; } } const enemies = []; // Scan level for enemies for (let r = 0; r < rows; r++) { for (let c = 0; c < cols; c++) { if (level[r][c] === 'E') { enemies.push(new Enemy(c * TILE, r * TILE)); } } } /* ---------- HELPERS ---------- */ function tileAt(x, y) { const cx = Math.floor(x / TILE); const cy = Math.floor(y / TILE); if (cx < 0 || cy < 0 || cx >= cols || cy >= rows) return '#'; return level[cy][cx]; } function isSolidAt(x, y) { const t = tileAt(x, y); return t === '#'; } function isHazardAt(x, y) { const t = tileAt(x, y); return t === 'F' || t === 'W'; } function isTrophyAt(x, y) { return tileAt(x, y) === 'T'; } function isExitAt(x, y) { return tileAt(x, y) === 'X'; } /* ---------- INPUT ---------- */ const keys = {}; window.addEventListener('keydown', e => keys[e.key] = true); window.addEventListener('keyup', e => keys[e.key] = false); /* ---------- GAME LOOP ---------- */ let gameOver = false; let win = false; function update() { if (gameOver || win) return; // Horizontal movement player.vx = 0; if (keys['ArrowLeft'] || keys['a']) player.vx = -PLAYER_SPEED; if (keys['ArrowRight'] || keys['d']) player.vx = PLAYER_SPEED; if ((keys['ArrowUp'] || keys['w'] || keys[' ']) && player.onGround) { player.vy = JUMP_SPEED; player.onGround = false; } // Apply gravity player.vy += GRAVITY; // Move X axis with collision player.x += player.vx; if (player.vx !== 0) { // check left/right collisions const left = player.x; const right = player.x + player.w; const top = player.y + 1; const bottom = player.y + player.h - 1; if (player.vx > 0) { // moving right if (isSolidAt(right, top) || isSolidAt(right, bottom)) { player.x = Math.floor((right) / TILE) * TILE - player.w - 0.01; } } else { // moving left if (isSolidAt(left, top) || isSolidAt(left, bottom)) { player.x = Math.floor((left) / TILE + 1) * TILE + 0.01; } } } // Move Y axis with collision player.y += player.vy; player.onGround = false; const left = player.x + 1; const right = player.x + player.w - 1; const top = player.y; const bottom = player.y + player.h; if (player.vy > 0) { // falling if (isSolidAt(left, bottom) || isSolidAt(right, bottom)) { player.y = Math.floor(bottom / TILE) * TILE - player.h; player.vy = 0; player.onGround = true; } } else if (player.vy < 0) { // jumping if (isSolidAt(left, top) || isSolidAt(right, top)) { player.y = Math.floor(top / TILE + 1) * TILE; player.vy = 0; } } // Check hazards if (isHazardAt(player.x + player.w/2, player.y + player.h/2)) { gameOver = true; alert('You died!'); } // Check trophy if (!player.hasTrophy && isTrophyAt(player.x + player.w/2, player.y + player.h/2)) { player.hasTrophy = true; } // Check exit if (player.hasTrophy && isExitAt(player.x + player.w/2, player.y + player.h/2)) { win = true; alert('You win! 🎉'); } // Update enemies for (const e of enemies) { e.update(); // Simple collision with player (instant death) if (rectsOverlap(player, e)) { gameOver = true; alert('Killed by an enemy!'); } } } function rectsOverlap(a, b) { return a.x < b.x + b.w && a.x + a.w > b.x && a.y < b.y + b.h && a.y + a.h > b.y; } function draw() { // Clear ctx.clearRect(0,0,width,height); // Draw level for (let r=0; r<rows; r++) { for (let c=0; c<cols; c++) { const ch = level[r][c]; const x = c * TILE; const y = r * TILE; if (ch === '#') { // wall ctx.fillStyle = '#555'; ctx.fillRect(x,y,TILE,TILE); } else if (ch === 'F') { // fire ctx.fillStyle = '#c33'; ctx.fillRect(x,y,TILE,TILE); } else if (ch === 'W') { // water ctx.fillStyle = '#33c'; ctx.fillRect(x,y,TILE,TILE); } else if (ch === 'T') { // trophy ctx.fillStyle = '#ff0'; ctx.fillRect(x+8,y+8,TILE-16,TILE-16); } else if (ch === 'X') { // exit ctx.fillStyle = '#0f0'; ctx.fillRect(x+4,y+4,TILE-8,TILE-8); } } } // Draw enemies ctx.fillStyle = '#f90'; for (const e of enemies) { ctx.fillRect(e.x+2, e.y+2, e.w-4, e.h-4); } // Draw player ctx.fillStyle = player.hasTrophy ? '#ff0' : '#fff'; ctx.fillRect(player.x+2, player.y+2, player.w-4, player.h-4); } function loop() { update(); draw(); requestAnimationFrame(loop); } requestAnimationFrame(loop); </script> </body> </html> ```

TAKE IT TO CODE

This run produced no artifact — reuse the prompt with a different model or your own pi-agent run.

RUN

modelgpt-oss-120b
vendorOpenAI
harnesspi-agent
generated2026-07-22

METRICS

runtime
tokens in1.2k
tokens out2.6k
cached0
cost / run$0.0005