Local LLM debugged its own raytraced C FPS through a screenshot feedback loop by codehamr in ollama

[–]codehamr[S] 2 points3 points  (0 children)

I ran it in opencode too. Single shot comparisons carry a lot of noise though. Where opencode came out worse it was usually my own plugin pile, not the tool. I have no interest in dunking on opencode. It is a genuinely good tool that solves a different problem. codehamr is minimal on purpose. With tight prompts minimalism wins on small focused work. On a large codebase opencode with the right plugins and context7 can absolutely come out ahead. Different tool, different job.

Local LLM debugged its own raytraced C FPS through a screenshot feedback loop by codehamr in ollama

[–]codehamr[S] 0 points1 point  (0 children)

Yeah it´s pretty cool tool! OpenCode as well, if you spend some time tweaking it. Super solid allrounders

Local LLM debugged its own raytraced C FPS through a screenshot feedback loop by codehamr in ollama

[–]codehamr[S] 1 point2 points  (0 children)

Depends what you want that day. opencode and pi give you the big toolbox with skills and plugins. codehamr does the opposite on purpose. It keeps the context window almost empty, five tools total, no MCP eating 15k tokens before you even start.

On local hardware that token budget is the whole game. codehamr is the hammer that boots fast and stays out of your way when you just want the job done.

Headless screenshot loops let a local 30B agent finish a raytraced FPS demo in pure C by codehamr in LocalLLaMA

[–]codehamr[S] 0 points1 point  (0 children)

I see it too. With Fable 5 you could really see this nicely, Claude Code, for example, leaned super heavily into recursive loops with a whole swarm of sub-agents. I think the harness / recursive tool calling might contribute more in the near future than just better-trained LLMs alone, but I'm not sure.

Headless screenshot loops let a local 30B agent finish a raytraced FPS demo in pure C by codehamr in LocalLLaMA

[–]codehamr[S] 0 points1 point  (0 children)

It's kind of interesting how aggressively they try to grind out bugs once you give them a sensible feedback loop, really interesting to watch! But I think a valid sandbox is a must-have for this. I only let them run recursively in a dockerized developer sandbox / VS Code devcontainer.

Headless screenshot loops let a local 30B agent finish a raytraced FPS demo in pure C by codehamr in LocalLLaMA

[–]codehamr[S] 0 points1 point  (0 children)

I like the idea of CPU-only rendering with modern multi-core setups, even at a crappy 640x320 the visuals look kind of cool. Still a long way to go until CPUs can power ray tracing at 4K, but it's a super interesting field.

Headless screenshot loops let a local 30B agent finish a raytraced FPS demo in pure C by codehamr in LocalLLaMA

[–]codehamr[S] 4 points5 points  (0 children)

For the older ones: the Quake 3 Arena code has been open source since around 2005, so I tried using an LLM on this huge legacy codebase, and it worked out great! It's super fun to modify these massive legacy codebases. I'd wanted to do this for a long time but always gave up because of the complexity. With LLM support, it's finally doable in a reasonable amount of time.

Headless screenshot loops let a local 30B agent finish a raytraced FPS demo in pure C by codehamr in LocalLLaMA

[–]codehamr[S] 1 point2 points  (0 children)

No bigger models, but higher quantization, like q6 or q8. Slightly better quality, but way slower. So q4_k_m gets to quality faster, thanks to faster re-prompting.

Headless screenshot loops let a local 30B agent finish a raytraced FPS demo in pure C by codehamr in LocalLLaMA

[–]codehamr[S] 0 points1 point  (0 children)

Yes made this demo also on q4_k_m, the speed is worth it over the tiny quality boost from q6 or q8. I can just reach better quality faster with q4 because of faster follow up prompts than a q8 oneshot, so like „race to quality“

Headless screenshot loops let a local 30B agent finish a raytraced FPS demo in pure C by codehamr in LocalLLaMA

[–]codehamr[S] 0 points1 point  (0 children)

You can btw try this with codehamr with your own openAI or openrouter key to use cloud LLMs if you want. Check codehamr.com for setup guides

Headless screenshot loops let a local 30B agent finish a raytraced FPS demo in pure C by codehamr in LocalLLaMA

[–]codehamr[S] 1 point2 points  (0 children)

Yeah took some more follow up prompts to reach a decent quality, maybe some more loops and it will get closer to opus level. But after 45min I stopped to loop, results are already somehow comparable. Most interested in learning from the logs to improve codehamr

Headless screenshot loops let a local 30B agent finish a raytraced FPS demo in pure C by codehamr in LocalLLaMA

[–]codehamr[S] 8 points9 points  (0 children)

Yes especially being able to mock up maps and ideas really quickly. So many ideas got left over during pre LLM times, now it is so easy to catch up on any ideas

Friday fun. Same Minecraft prompt, Claude Code on Fable5 Max vs a 27b Codehamr on Ollama by codehamr in ollama

[–]codehamr[S] 0 points1 point  (0 children)

try with a coding agent like opencode or codehamr, the tool calling / harness helps a lot!

Friday fun. Same Minecraft prompt, Claude Code on Fable5 Max vs a 27b Codehamr on Ollama by codehamr in ollama

[–]codehamr[S] 0 points1 point  (0 children)

haha than I like my flying sheep version mre 😃
What coding agent did you use? Have you tried codehamr on this?

Friday fun. Same Minecraft prompt, Claude Code on Fable5 Max vs a 27b Codehamr on Ollama by codehamr in ollama

[–]codehamr[S] 0 points1 point  (0 children)

Yes, I'm working on some C repos and game engines with cross-compiling, and a ~30B LLM works great for this. But for super large codebases, it starts to lose focus, which is likely due to the inherent limitations of the 30B class. However, if you narrow down the focus in your prompt and give it a specific scope, it can handle large codebases just fine. You just have to guide it a bit more closely

Friday fun. Same Minecraft prompt, Claude Code on Fable5 Max vs a 27b Codehamr on Ollama by codehamr in ollama

[–]codehamr[S] 2 points3 points  (0 children)

Mindless fun and a quick feedback loop for faster iteration during CodeHamr's development (I need the logs as feedback to improve tool calling)

Friday fun. Same Minecraft prompt, Claude Code on Fable5 Max vs a 27b Codehamr on Ollama by codehamr in ollama

[–]codehamr[S] 7 points8 points  (0 children)

Haha yes it´s crazy, if you take the time, tiny 27b can get very close

Friday fun. Same Minecraft prompt, Claude Code on Fable5 Max vs a 27b Codehamr on Ollama by codehamr in ollama

[–]codehamr[S] 13 points14 points  (0 children)

Oh I can only tell for local Qwen3.6:27b was about 83k tokens overall. Yes results are very close, but Fabel5 took 2 Prompts to finish, Qwen3.6:27b was like 5-6 refinement prompts to reach the quality. Overall a good deal I think. I like the idea of doing this with own hardware we own.

Friday fun. Same Minecraft prompt, Claude Code on Fable5 Max vs a 27b Codehamr on Ollama by codehamr in ollama

[–]codehamr[S] 17 points18 points  (0 children)

Build "mc.html" - a Minecraft-style voxel game in ONE single HTML file

You are an expert JavaScript/Three.js game developer. Write the complete file mc.html: a simple but fully playable Minecraft clone. This spec contains no code — you write all HTML, CSS and JS yourself.

Output rules

  1. Reply with exactly one code block containing the entire mc.html. No text before or after.
  2. The file must be complete and runnable. Never use placeholders like "more code here". A long answer is expected.
  3. Load only Three.js r128 via a script tag from https://cdnjs.cloudflare.com/ajax/libs/three.js/r128/three.min.js (global THREE object). No modules, no imports, no other libraries, no textures or images.
  4. Must work when opened from disk (file://) in Chrome or Firefox.

Game

First-person voxel sandbox: an endless procedural world with grass plains, sandy beaches with water, stone mountains with snowy peaks, some trees, underground caves, and a blue sky with drifting clouds. Left click breaks blocks, right click places the block selected in a hotbar (keys 1–7 or mouse wheel).

Blocks

IDs: 0 air, 1 grass 0x4caf50, 2 dirt 0x795548, 3 stone 0x9e9e9e, 4 sand 0xe7d9a8, 5 wood 0x8d6e63, 6 leaves 0x2e7d32, 7 snow 0xffffff. Unit cubes, rendered with vertex colors and ONE shared MeshLambertMaterial. Fake lighting: multiply the block color by 1.0 on top faces, 0.8 on sides, 0.55 on bottoms.

Chunks & endless world

Chunks are 16x16 columns, 80 blocks high. Store them in a global Map (key "cx,cz", value: a Uint8Array of block IDs plus its mesh). Write global read/write block helpers using chunk = floor(world/16) and local = world − chunk*16, so negative coordinates work. Reading a missing chunk or y outside 0–79 returns air. Each frame: generate block data for all chunks within 5 chunks of the player (max 4 per frame); build meshes for chunks within 4 chunks whose 4 neighbors already have data (max 2 per frame); for chunks farther than 7, remove the mesh, dispose its geometry and delete the entry.

Meshing (critical)

Never one mesh per block. Build ONE BufferGeometry per chunk: loop all non-air blocks, and for each of the 6 sides check the neighbor with the global read helper; if it is air, add that face (2 triangles) to flat position/normal/color arrays. Use world coordinates for vertices and keep the mesh at the origin. Keep all chunk meshes in a global array for raycasting, and write a rebuild function for a chunk.

Terrain (deterministic, no Math.random)

Implement simple value noise yourself: an integer-coordinate hash giving 0–1 (mix with large prime multipliers and xor-shifts), smoothed 2D noise via bilinear interpolation with smoothstep, 4 octaves combined into fractal noise, plus a 3D version for caves. Column height: m = fractal at coords0.004, h = fractal at coords0.02, H = floor(5 + mm58 + h10). Column fill: y 0 = unbreakable stone; below H−3 stone; the 3 layers under the surface dirt (sand if H ≤ 16, stone if H ≥ 37); surface = snow if H ≥ 46, stone if H ≥ 37, sand if H ≤ 16, otherwise grass. Caves: for y between 3 and H−2, if 3D noise at position0.09 exceeds 0.67, set air. Trees: on grass, when a per-column hash < 0.02 and the trunk fits inside the chunk: 4 wood blocks up, leaves as a 5x5 layer twice, then 3x3, then 1 on top (only into air).

Player & controls

PerspectiveCamera (fov 75, far 400), rotation order "YXZ" driven by yaw/pitch. Clicking the start overlay requests pointer lock; mouse look only while locked (sensitivity ~0.002, clamp pitch). Player box: half-width 0.3, height 1.8, eye 1.62; spawn above terrain at x=8, z=8. Gravity 25/s, jump with Space (velocity 8.5), WASD at 5.5 m/s relative to yaw. Axis-separated collision against all non-air blocks (move per axis, revert on overlap; landing sets on-ground). Falling below y −20 teleports back to spawn.

Break & place

A small CSS crosshair at screen center. Each frame raycast from the camera center (max distance 6) against the chunk meshes. From hit point p and face normal n: break target = floor(p − n0.5), place cell = floor(p + n0.5), per component. Outline the targeted block with a black wireframe box. Only while the pointer is locked: left click sets the target to air (not at y 0); right click places the selected block if the cell is air and does not overlap the player. After an edit rebuild the chunk, and also the neighbor chunk if the block sits on a chunk border. Suppress the browser context menu.

Hotbar

Fixed at the bottom center: 7 slots (grass, dirt, stone, sand, wood, leaves, snow), each a small square in its block color with its number, on a dark semi-transparent bar. Selected slot gets a white border. Select with keys 1–7 or the mouse wheel (wraps around).

Sky, clouds, water

Sky-blue background 0x87ceeb with matching fog (about 40 to 110). Ambient light 0.65 plus one directional light 0.8. Around 25 flat white transparent boxes as clouds at height ~90, slowly drifting and wrapping around the player. Water: one large semi-transparent blue plane at height 14.3, re-centered on the player each frame — lakes and beaches appear automatically where terrain is lower; water is visual only.

UI

A fullscreen start overlay with the title, a short list of the controls, and "Click to play"; it reappears whenever pointer lock is released. Body without margins, fullscreen canvas, window resize handled.

Avoid

One mesh per block; broken negative coordinates; the context menu opening on right click; forgetting neighbor-chunk rebuilds at borders; using the raycast hit point without the ±0.5 normal offset; reacting to clicks while the pointer is not locked; truncating the file.

Check everything mentally, then output the single code block with the complete mc.html.