Wolfenstein raycaster · gemma-4-26b-a4b-it
Output generated Cost / run $0.0029 Runtime 80.9s
Prompt for this run
Build a playable first-person raycasting maze shooter on a canvas in a Wolfenstein-inspired style. Use HTML, CSS, and JavaScript as needed. Write it to `index.html` in the current working directory using your file tools. Inline your own CSS and JavaScript. Do not use external assets, CDNs, or network requests. No third-party libraries are provided. Required behavior: - Render a textured grid maze through a raycaster, with perspective wall heights and visible enemies. Generate textures procedurally; do not load external assets. - Use W/S to move forward/backward, A/D to strafe, Left/Right arrows to turn, and Space to shoot. Display the controls. Mouse turning is optional and must not be required. - Use solid wall collision and a small level with a reachable exit and at least three enemies. Enemies must be occluded by walls; shots cannot damage an enemy through a wall. - Give the player health. Enemies can damage the player under a clear attack rule. Show health and remaining enemy count; zero health causes Game Over. - Defeating all enemies unlocks the exit; reaching it shows a win state. Provide Restart to restore the level, player, enemies, and health. Verify: Test movement and turning near the starting area, check collision against a nearby wall, and fire to inspect weapon feedback. Sample the scene for stable wall rendering, then use Restart and check the initial viewpoint and health.
TAKE IT TO CODE
A single self-contained HTML file — copy it and open in any browser, or reuse the prompt with your own pi-agent run.
RUN
METRICS
Transcript · 5 messages
Build a playable first-person raycasting maze shooter on a canvas in a Wolfenstein-inspired style. Use HTML, CSS, and JavaScript as needed. Write it to `index.html` in the current working directory using your file tools. Inline your own CSS and JavaScript. Do not use external assets, CDNs, or network requests. No third-party libraries are provided. Required behavior: - Render a textured grid maze through a raycaster, with perspective wall heights and visible enemies. Generate textures procedurally; do not load external assets. - Use W/S to move forward/backward, A/D to strafe, Left/Right arrows to turn, and Space to shoot. Display the controls. Mouse turning is optional and must not be required. - Use solid wall collision and a small level with a reachable exit and at least three enemies. Enemies must be occluded by walls; shots cannot damage an enemy through a wall. - Give the player health. Enemies can damage the player under a clear attack rule. Show health and remaining enemy count; zero health causes Game Over. - Defeating all enemies unlocks the exit; reaching it shows a win state. Provide Restart to restore the level, player, enemies, and health. Verify: Test movement and turning near the starting area, check collision against a nearby wall, and fire to inspect weapon feedback. Sample the scene for stable wall rendering, then use Restart and check the initial viewpoint and health.
thinking
The objective is to build a single-file `index.html` that contains a first-person raycasting maze shooter in a Wolfenstein-inspired style.
* Raycasting engine (rendering textured walls/floors).
* Procedural textures (no external assets).
* Player movement: W/S (forward/backward), A/D (strafe), Left/Right arrows (turn).
* Shooting: Spacebar.
* Collision: Solid walls, maze layout.
* Enemies: At least three, must be occluded by walls, can be shot.
* Combat: Player health, enemies damage player, shots damage enemies.
* Win/Loss:
* All enemies defeated -> Exit unlocked.
* Reach exit -> Win.
* Zero health -> Game Over.
* Restart button to reset everything.
* UI: Display controls, health, enemy count.
* *Raycaster*: Use DDA (Digital Differential Analyzer) for efficient raycasting.
* *Textures*: Generate pixel arrays for walls, floors, and enemy sprites in memory.
* *Map*: A 2D grid representing walls.
* *Enemies*: Sprites with distance and angle calculations.
* *Game Loop*: `requestAnimationFrame` for rendering and logic updates.
* *Collision*: Check grid positions during movement.
* *Visibility*: Raycasting to check if an enemy is visible (occlusion check).
* `canvas`: For rendering.
* `ui`: Overlays for HUD, Game Over, Win, and Controls.
* *Textures*: Use a small canvas to draw patterns (bricks, noise, etc.) and then use `getImageData` to get pixel buffers.
* *Movement*: Update $(x, y)$ and $\theta$ (angle).
* *Rendering Engine*:
* Step 1: Draw floor and ceiling.
* Step 2: Raycasting for walls (DDA).
* Step 3: Sprite rendering (enemies).
* Step 4: HUD/UI.
* *Collision Check*:
* For movement: `map[newY][newX] == 0`.
* For visibility: Cast a ray to the enemy's position to see if it hits a wall first.
* *Textures*:
* Wall: Red/brown brick pattern.
* Floor: Greyish stone.
* Ceiling: Dark grey/blue.
* Enemy: Simple colored sprite (e.g., green/yellow blob).
* *Map*: A $16 \times 16$ or $24 \times 24$ grid.
* Player: `x`, `y`, `dir`, `plane` (for raycasting), `health`, `score`.
* Enemies: `x`, `y`, `active`, `health`.
* GameState: `START`, `PLAYING`, `GAMEOVER`, `WIN`.
* *DDA Step*: Find the next grid line.
* *Sprite Rendering*: Calculate distance, check if within view frustum, check if occluded (important!).
* *Occlusion*: For each enemy, cast a ray from player to enemy. If it hits a wall before the enemy, the enemy is occluded.
* Writing the code into `index.html`.
* Running it in the browser.
* Testing.
*Self-Correction/Refinement during drafting:*
* *Occlusion*: Checking occlusion by casting a ray to the enemy center might be jittery if not careful. A better way is to use the Z-buffer or just cast a ray to the enemy's position in the DDA loop.
* *Texture generation*: Since I can't use external assets, I'll use `canvas.getContext('2d').createImageData` to generate some basic textures (bricks, noise).
* *Sprite*: I'll represent enemies as billboarded sprites.
*Plan for index.html:*
- HTML structure: `<canvas>`, `<div id="ui">`.
- CSS: Absolute positioning for UI, full screen.
- JS:
- Constants/Config.
- Texture generator.
- Map generation.
- Input handling.
- Game loop.
- Raycasting implementation.
- Sprite/Enemy implementation.
- Collision detection.
- UI/HUD updates.
Let's start coding.index.html (20339 bytes)Successfully wrote to index.html
thinking
The user wants a playable first-person raycasting maze shooter.
I have written the `index.html` with a raycaster, but I noticed in my implementation that I used simple color blocks instead of true textured walls to ensure performance and stability, but the prompt *specifically* asks for "textured grid maze". I should try to implement textures more properly if possible, or at least make the walls look more like bricks using pattern drawing.
Also, the current `render` function has a potential performance issue if I try to do pixel-by-pixel rendering in JS. However, I can use `ctx.drawImage` to draw segments of a texture.
Wait, I see I implemented `generateTextures` but I'm not using them in the `render` loop for the walls. I'm just using `ctx.fillRect`.
Let's improve the `render` function to actually use the textures. I'll use a vertical slice approach.
Revised Plan for `render`:
1. For each vertical strip of the wall (column `x` from 0 to `width-1`):
- Calculate the wall's height and the corresponding texture slice.
- Since `ctx.drawImage` with source/destination can work, I can draw a slice of the wall texture.
However, calculating the texture coordinates for each pixel is more robust. In pure JS, I'll iterate over the vertical strip and draw the texture column.
Also, let's check the collision and enemy logic.
The enemy visibility check `isLineOfSight` is present.
The movement and rotation are present.
The shoot cooldown is present.
The win/loss states are present.
Let's refine the `render` function to be more "textured" and "Wolfenstein-style".
I'll also add the floor texture.
Let's test the current version first to see if it works as a base. I'll use the `browser` tool.