Qwen3.6 27B local vs Opus 4.8, voxel engine in raw C with zero frameworks

Sunday experiment. Same prompt to both. Build a voxel world in plain C. No engine, no game library, no framework, just the compiler. The model does its own chunk meshing, render loop and memory management by hand.

Left is Claude Code on Opus 4.8. Right is Qwen3.6 27B local on vLLM, the new NVFP4 quant, 256k context. Runs around 130 TPS on an RTX 6000 Blackwell 96GB through my own coding agent.

Opus clearly understands voxel physics. Terrain holds, chunks line up, collision works. The 27B compiles and renders, then tears itself apart on screen.

The quality gap I expected. What I did not expect was a local 27B handling C at all. Almost every local demo is Python or TypeScript with a framework doing the work. Strip that away and you are left with raw pointers and manual allocation, exactly where I assumed a quantized model would fall over. It did not. Rough, but it builds and runs.

Everyone watches the frontier race. Nobody talks about the bottom catching up. Two years ago this prompt gave you a segfault on a local model. Now it gives you a broken world that still runs on a card under your desk. The ceiling barely moved. The floor sprinted.

u/codehamr — 8 days ago
▲ 11 r/ollama

turns out a local ollama 27B LLM can write vanilla C, not just Python and TypeScript

Just messing around on a Sunday. Same prompt to both. Build a tiny voxel world in vanilla C, no engine, nothing past the standard toolchain. Left is Claude Code on Opus 4.8, right is Qwen3.6 27B local through Ollama / codehamr.

Opus clearly gets voxel physics. Terrain holds together, chunks line up, collision works. The local model shipped something that compiles and renders, then tears itself apart on screen.

The takeaway for me was not the quality gap, that was expected. It was that a 27B handles oldschool C-Programming at all. Almost every local coding demo is Python or TypeScript, so I assumed manual memory and pointer math would just fall over on a quantized model. It did not. Output is rough but it builds and runs.

Everyone watches the top models race each other. The thing nobody talks about is the bottom catching up. Two years ago this same prompt gave you a crash on a local model. Now it gives you a broken world that still runs. The top barely moved. The bottom sprinted.

Repo if you want https://github.com/codehamr/codehamr

u/codehamr — 8 days ago
▲ 316 r/ollama

Local Ollama Qwen3.6:27B at 100 TPS now beats my capped Opus4.8 for simple work

Same laser cutter physics prompt to Opus 4.8 and a local Qwen3.6 27B on Ollama. Slice a gray wall into real polygon shards with a laser. Screenshot of both below.

Quality first and I will be fair. Opus feels smoother to cut with. Cleaner aim, shards settle a bit better. But neither nailed it in one shot. Both cut perpendicular to the wall at the impact point instead of along the beam direction. The laser looks right, the geometry it carves is wrong. Same failure on both sides.

The part that made me laugh. The local 27B on a Nvidia 5090 runs north of 100 tokens per second. My Opus in Europe is now capped around 50 tokens per second. In my own setup the frontier cloud model is the slow one.

What I care about is quality per time box, not quality per token. While Opus grinds through its first pass, the local model is already done. So I fire the second refinement prompt inside the same wall clock Opus needs for one answer. Two local rounds against one cloud round, same elapsed time. It turns into a race to quality, and the faster model gets more attempts in the same window. For simple tasks that often closes the gap, because more refinement beats one better shot.

Cloud still wins on raw capability per response. It just stopped winning on what I can ship in five minutes. The local rig even feels more premium now, purely because it answers while I am still thinking.

The local side ran through codehamr, a local first coding agent, free and open source if you want to try it yourself. https://github.com/codehamr/codehamr

u/codehamr — 12 days ago
▲ 35 r/ollama

Local LLM debugged its own raytraced C FPS through a screenshot feedback loop

For months my local Ollama coding agent experiments were the easy stuff. Single file three.js games, Minecraft clones, oneshot HTML demos. All of it sits deep in the training data, so a side by side quality comparison was never the point. What made them useful is that I can debug them by eye in a second. That fast visual feedback is what let me tune the harness, the tool calling and the agent loop until they actually held up.

This week I pushed Qwen3.6 27B on Ollama at something harder. A small raytraced FPS demo in pure C, standard library only. It could not oneshot it, same as the frontier model I ran alongside.

Yes, C raytracers are in the training data too. Rarer than three.js, but they are there. And before LLMs most of us were doing pattern reuse anyway. Stack Overflow, docs, copy the shape that works, adapt it. Reusing a good pattern is not cheating, it is the job. So that is not the point either.

Then I changed one thing in the prompt. The compiled binary had to ship a headless mode where the agent could inject keyboard and mouse input and grab a screenshot at a chosen frame.

That flipped it. The model worked out on its own how to time the screenshots around what it wanted to inspect. Fire a rocket, capture the frame at impact, check the particle effects, fix, run again. A recursive visual debugging loop it drove itself.

I learned C from scratch back in the day, so watching a 27B model on local Ollama debug a raytracer off its own screenshots is not what I expected this size to pull off. It costs you in runtime and tokens, but it works.

This runs on codehamr, my own free and open source coding agent. The Ollama setup guide and the GitHub link live at https://codehamr.com if you want the details.

u/codehamr — 17 days ago

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

Some background so this is honest. Over the past few months I ran a lot of oneshot experiments with single file three.js games. Minecraft clones, that kind of thing. I picked those on purpose because they sit deep in the training data and are trivial to debug by eye. The goal was never a quality comparison. I wanted a class of problems that oneshots cheaply and that I can inspect visually and from logs, so I could tune the harness, the system prompt and the tool calling.

This week I made it harder. I had Claude Code on Opus 4.8 and a local Qwen3.6 27B agent both write a small raytraced FPS demo in C, standard library only.

Yes, C raytracers are in the training data too. Rarer than three.js, but they are there. And let us be honest, before LLMs most of us were doing pattern reuse anyway. Stack Overflow, docs, copy the shape that works, adapt it. Reusing a good pattern is not cheating, it is the job. So that is not the point.

The point is one prompt change. Both struggled to oneshot this. Then I added a single requirement. The compiled binary had to ship a headless mode where the agent could inject keyboard and mouse input and trigger a screenshot at a chosen frame.

That flipped it. The model worked out on its own that it should time the screenshots around the events it wanted to inspect. Fire a rocket, capture the frame right at impact, look at the particle and debris effects, fix what is wrong, run again. It built itself a recursive visual debugging loop.

The frontier model finishing is not surprising. Qwen3.6 27B closing the same loop on its own is the part that stuck with me. I learned C from scratch back in the day, so watching a small local agent debug a raytracer by looking at its own screenshots was not what I expected this size of model to pull off. It costs you though. Longer runtime, a lot more tokens, more wall clock per iteration.

This reads more as a prompting lesson than a model lesson. Give the agent a way to see the result and let it pick when to look, and fairly hard problems come into reach for a small local model.

Curious whether anyone has pushed the screenshot feedback idea further. Video frames instead of stills, or letting the model script longer input sequences before it captures.

Full disclosure, the local agent is codehamr, my own open source project, so weigh the comparison with that in mind. Code is open if you want to run it yourself. https://github.com/codehamr/codehamr

u/codehamr — 19 days ago
▲ 264 r/GeminiAI+1 crossposts

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

Friday felt like the right day to build something completely unnecessary, so I built Minecraft twice.

Left side is Claude Code on Fable5 Max, about the strongest setup you can currently rent. Right side is qwen3.6 27b, fully local through Ollama, driven by codehamr, a small Go coding agent I wrote.

Honesty first. This says very little about model intelligence. Every current model has digested hundreds of Minecraft clones during training, so a prompt like this is closer to recall than to engineering. That is also why a 27b can hang with a frontier model on this task at all.

Still fun though. The local side took 5 or 6 prompts and roughly 30 minutes. Terrain, chunks, placing and breaking blocks, hotbar, all there after the first or second attempt.

And then the sheep. Both models cruised through the hard parts and both faceplanted on the sheep, each in its own way. The local one decided sheep live in the sky now.

Agent code lives at github.com/codehamr/codehamr if anyone wants to poke around. All free all open source all optimized for local ollama usage.

u/Smart_Primary2526 — 22 days ago
▲ 106 r/LocalLLM

another trash shooter as an LLM benchmark, locally generated in 15min

I am old and I like boomer shooters. Grew up on Doom and Quake, learned to code in C counting bytes.

I like opencode and pi, I just kept wanting something dumber. No skills, no MCP, no plugin tree to babysit. So I built a tiny coding agent, codehamr, and put it free and MIT on GitHub. https://github.com/codehamr/codehamr

Pointed it at Qwen3.6 locally and asked for a single file html shooter with three.js and that early 90s look. Brown corridors, hitscan weapons, a strafe that feels wrong in the right way.

15 minutes later it was playable. Rough, but the genre I grew up in.

The part that gets me is it ran fully local. A year ago this was a cloud only trick. Now a local model does it while I make coffee. Anyway, just a passion project for fun, hope this helps someone.

u/codehamr — 27 days ago
▲ 2 r/ollama

same simple todo app, frontier vs local, side by side build

Video sped up at the beginning, just for a first impression.

Ran both at once, Opus 4.8 and a local qwen3.6 27b on an Nvidia RTX 6000. Speed was not really the focus here, both finished in about the same time anyway. The point is that basic local coding can now match the quality of a high end LLM without much trouble. No meter running, no monthly subscription, assuming you have the hardware.

Repo if you want to try it yourself: github.com/codehamr/codehamr

Prompt I used:

>

I built codehamr out of pure interest and because I wanted something more lightweight and simpler than opencode or pi. Both are great tools, I just wanted something smaller and less token hungry, to use limited local hardware more wisely.

u/codehamr — 27 days ago

Would a prepaid pass for a coding agent solve a real need or is it just my itch?

codehamr in action

Claude Code does its job well but it wears you down. Session limits before deadlines, quality that feels like it drops some weeks, opaque token burn. Pay as you go fixes the limits but frontier pricing is brutal.

So I built codehamr. opencode and pi are great tools, I just wanted something minimal. A single Go binary, MIT, no plugins, no login. It is designed local LLM first with a lean loop that burns few tokens, so it runs well on small models and stays cheap.

The experiment. A prepaid pass for everyone without a GPU. One key, never expires, I keep it pointed at whatever open model wins on price and quality that month. Few tokens plus cheap models, the pass lasts a long time.

Yes, OpenRouter works too, the agent supports it. The pass is for devs who would rather pay a little than babysit a LLM leaderboard.

Waitlist is on codehamr.com

A signup tells me more than any comment. If it is a dumb idea, say so, that helps too.

reddit.com
u/codehamr — 1 month ago
▲ 10 r/ollama

Q4_K_M vs FP8 on Qwen3.6 27B. A note on iteration speed to quality

Q4_K_M vs FP8 on Qwen3.6 27B

Follow up from my last thread where some of you asked for an FP8 comparison.

FP8 did win the one shot, the output quality was slightly better. But in the refinement phase it fell behind. Q4_K_M runs at up to 110 tps versus around 47 tps for FP8 on my local hardware, so each follow up round costs less than half the time.

So in the same overall time Q4 just grinds through more iterations and catches up on quality faster than FP8 can extend its lead.

One simple prompt scenario, my personal experience, no general claim. But it was an interesting observation. For iterative work the cheaper round trip seems to matter at least as much as one shot quality.

Curious if anyone has compared quants on iteration speed instead of one shot quality.

reddit.com
u/codehamr — 1 month ago
▲ 121 r/ollama

Claude Code Opus 4.8 vs. Local Qwen3.6 27B One-Shot Coding Benchmark

https://reddit.com/link/1twpep6/video/jc37584zz95h1/player

Full disclosure I built codehamr, the local agent on the right, as a passion project. I love local LLMs and wanted to see how close I could get to Claude Code using 27B models and strict prompt discipline.

I ran an identical prompt specifically requesting a retro pixel art space game. This is a great way to push a coding agent because it is complex enough to test one-shot capability while remaining visually obvious if it hit the mark. I used no retries or manual edits to show the raw first output.

Opus is clearly ahead on general polish, but the 27B result is a functional game built entirely on hardware under my desk. The gap is surprisingly small.

You can check out a polished version at codehamr.com/example, but the video shows the raw result. It is clear that for 27B models, rigorous prompt discipline is the deciding factor in making them perform at this level.

reddit.com
u/codehamr — 1 month ago
▲ 146 r/AIDeveloperNews+1 crossposts

What I missed from C and how Go gave it back

Spent years in python. Before that I shipped C binaries way back when. Something about a single self contained executable always felt right to me, and Go gave me that feeling back.

The cross compile and binary distribution are the parts I missed most from my C days. Building once on my machine and shipping linux, macOS, windows times amd64 and arm64 in seconds with goreleaser feels almost too easy after years of fighting python interpreters. curl pipe bash and you have a working tool.

The footprint is the other piece. 15MB binary, starts in milliseconds. After watching agents take seconds to boot on every invocation, that alone changes how I use them.

Recently built a small coding agent in Go and the language carried more of the load than I expected. Seven direct deps in go.mod, bubbletea for the TUI being the main one. Stdlib handled the rest.

Honestly happy with the choice. Feels like the first time in a while a language got out of my way instead of in it. Repo is a week old and single dev so capacity is limited, but if anyone wants to look: https://github.com/codehamr/codehamr

u/codehamr — 2 months ago
▲ 267 r/ollama

Hey folks. Been coding about 25 years. Heavy Claude Code user for over a year now.

Quick note before I start. Username here is the same as the project. Made a new account for this on purpose. Did not want to mix it with my main.

Claude Code is world class on quality and out of the box usability. No question. But the constant session limits and the silent shifts in code quality started to wear me down.

I kept reaching for opencode and pi during timeouts. Both are great. I really like them. When I am locked out mid task though, I do not need a Swiss army knife. I just want a small reliable agent in yolo mode that does not get in my way and finishes the task before my Claude window opens again.

So a few days ago I pushed my own thing to GitHub. MIT licensed.

Called codehamr: https://github.com/codehamr/codehamr

Single Go binary. Talks to any OpenAI compatible endpoint, so Ollama, vLLM, or whatever you point it at. I built it local first because I love how simple Ollama is and wanted that same feeling in the agent itself.

It does way less than opencode or pi. That is the point. Fast and out of your way.

Same prompt on both sides, simple FPS shooter. Claude Code with Opus 4.7 on the left. codehamr with Qwen3.6:27b at Q4_M on the right. Claude is still ahead, no surprise. But the gap is thinner than I expected.

Heads up. The repo is only a few days old. I am a single dev with limited time, but I am actively pushing improvements. If something breaks or you have feature ideas, open an issue and I will get to it.

If anyone else is tired of being chained to a session timer, maybe this scratches the itch. Curious what you build with it.

Here the prompt, have fun:

Create a single file `game.html` (HTML+CSS+JS+Three.js via CDN, NO build tools, NO external assets, NO postprocessing). On load the game world renders and simulates immediately. A single click anywhere acquires pointer lock for mouse-look – this is the only gate, no menu screen.


THREE.JS SETUP:
- Use an importmap in the HTML head pointing "three" to https://unpkg.com/three@0.160.0/build/three.module.js
- Import via `import * as THREE from 'three'` inside one `<script type="module">` block
- No EffectComposer, no postprocessing passes, no shader passes
- NO CSS vignette, NO radial darkening overlay, NO color-grade filters – the canvas renders edge-to-edge cleanly


GAME: Minimal Quake3-style arena shooter, first-person.


============================================================
CRITICAL FEEL REQUIREMENTS — these MUST NOT regress
============================================================


MOUSE LOOK — perfectly smooth, never jumpy, never inverted:
- Maintain two scalars on the player: `yaw` and `pitch` (both in radians).
- On `mousemove` while `document.pointerLockElement === canvas`:
      yaw   -= e.movementX * sensitivity
      pitch -= e.movementY * sensitivity
  Both signs are NEGATIVE. This gives the standard FPS convention:
  mouse right → look right, mouse up → look up. Do not flip them.
- Clamp pitch to [-Math.PI/2 + 0.001, Math.PI/2 - 0.001].
- Each frame, REBUILD the camera rotation from these scalars (do not rotate the camera incrementally — incremental rotation accumulates float drift and causes visible jumps and roll):
      camera.rotation.order = 'YXZ'
      camera.rotation.y = yaw
      camera.rotation.x = pitch
      camera.rotation.z = 0
- Sensitivity: 0.0022 rad/pixel. Apply as a single multiplier — 1 px of mouse delta produces exactly the same yaw/pitch delta every time. NO smoothing, NO lerp, NO acceleration curve, NO mouse-input buffer. Strict 1:1 mapping.
- Recoil and hit-feedback NEVER write to yaw/pitch. Camera-punch effects use a separate transient position/FOV offset only — the player's aim is sacred.


CURSOR HYGIENE — the OS cursor must never be visible during gameplay:
- CSS: `html, body { cursor: none; overflow: hidden; margin: 0; }`
- HUD overlay div: `pointer-events: none` so clicks always reach the canvas
- Pointer lock is requested from a user-gesture click handler only; guard against duplicate requests in the same frame
- On `pointerlockchange` with null target, auto-pause; on re-lock, resume


MOVEMENT — snappy and grounded, not floaty, not wobbly:
- Gravity: 28 ² (firm; 9.8 feels moony — do not use it)
- Walk speed: 7 , sprint: 11 
- Ground acceleration: 90 ² (reaches max speed in <0.1s — instant feel)
- Ground friction: 12 (decelerates predictably when no input)
- Air acceleration: 18 ² (limited air control, no wobble)
- Build the input vector from WASD in camera-yaw space ONLY (ignore pitch when projecting horizontal movement). Normalize before scaling.
- Integrate velocity straight from input + friction + gravity. Do NOT apply any spring/critically-damped smoothing to the input vector itself — that is what creates the "schwabbelig" feel.
- Reject NaN velocity and reset to zero each frame as a guard.


JUMP & LANDING — crisp, with subtle landing dip but zero input lag:
- Jump velocity: 9.0  on Space when grounded
- Coyote time: 90 ms (can still jump 90 ms after walking off an edge)
- Jump buffer: 120 ms (Space pressed up to 120 ms before landing still triggers a jump on touchdown)
- Landing dampening: when vertical velocity at touchdown is < -6 , apply a small `cameraOffsetY` (start at ~ -0.12 u, springs back to 0 over ~180 ms with critical damping). This offset is added AFTER rotation is set; it is purely visual and never affects controls or physics.


COLLISION — player must NEVER get stuck inside a wall, box, or corner:
- Player AABB: half-width 0.35, height 1.7, eye height 1.6
- Each frame, resolve movement axis-by-axis in order X → Z → Y:
    1. Add velocity.x*dt to position.x. For each static AABB, if overlap, push out along X by minimum penetration and zero velocity.x.
    2. Same for Z.
    3. Same for Y; +Y stop = ceiling, -Y stop = grounded (set canJump=true, store landing impact for landing-dip).
  Axis-by-axis naturally yields wall-sliding on diagonal input and prevents corner traps.
- DEPENETRATION PASS at the start of each frame: if the player AABB already overlaps any static AABB (spawn-glitch, ramp edge, lag spike), push out along the smallest-penetration axis. This guarantees recovery.
- Ramps: solid AABBs PLUS a downward feet-probe each frame; if grounded over a ramp's slanted top, snap player Y to the surface so they don't bounce down slopes.
- Bots use the same axis-by-axis resolution against walls/boxes (bots may overlap each other, that's fine).
- Clamp dt to ≤0.05 s in the loop so a tab-switch never tunnels the player through geometry.


============================================================


CONTROLS:
- WASD move, mouse look, Space jump, Shift sprint
- Left click = railgun shot (also acquires pointer lock if not yet locked)
- ESC toggles pause (overlay "PAUSED"); ESC again resumes. Release/request pointer-lock accordingly. Guard against double-toggle on a single key event.
- requestAnimationFrame natively (no manual cap); 120/144 Hz monitors get full refresh; simulation is delta-time and frame-rate-independent.


WEAPON – RAILGUN (only weapon, one-shot-one-kill):
- Hitscan via raycast, instant hit; bot hit = instant kill, always
- Cooldown ~1.2 s, visible thin cooldown bar at bottom center
- Heavy visual recoil on the camera ONLY (FOV punch + transient position offset, springs back over ~200 ms). Recoil never alters yaw/pitch.
- Beam: glowing thin cylinder/tube from muzzle to impact point, ~250 ms life, fades via opacity, with a brighter inner core line
- Muzzle flash: brief PointLight + small additive sprite quad at shot origin
- Wall impact: spark particles + small dark quad oriented to the hit-surface normal, offset 0.01 along the normal to avoid z-fighting (no DecalGeometry)
- WebAudio synth sound: short noise burst + descending sawtooth


VISUAL STYLE — ESPORTS-CLEAN, BRIGHT, READABLE (NOT dark, NOT moody):
- The arena should read clearly on a laptop in a lit room. Aim for "bright daylight scrim", not "dim corridor".
- NO vignette, NO radial darkening, NO color-grade overlays. The HUD div is fully transparent except for crosshair/text.
- Palette (use these exact hex values):
  - Background/sky:        #1A2230
  - Floor base:            #4A5360
  - Floor grid lines:      #6E7986
  - Wall base:             #545E6C
  - Wall grid lines:       #7A8492
  - Cover/ramps:           #5E6876
  - Accent (beam/HUD/marker): #B8EEFF
  - Bots:                  #E86A3C
- Lighting (bright and even):
  - HemisphereLight(skyColor=0xCFE3F5, groundColor=0x3B424E, intensity=0.85)
  - DirectionalLight(white, intensity=0.95) from above-front; soft shadows enabled
  - AmbientLight(0x404858, 0.25) to lift deep shadows
- Renderer: ACESFilmicToneMapping, exposure 1.15, outputColorSpace = THREE.SRGBColorSpace, clearColor matches sky
- Materials matte (MeshStandardMaterial, roughness ~0.85, metalness 0); only beam/HUD/bot accents slightly emissive
- Glow faked with emissive materials and additive sprite quads — no bloom
- HUD typography: thin sans-serif (system-ui), thin lines, lots of negative space


MAP (procedural, deterministic with seed):
- Square arena ~50×50 units, walls 4 units tall
- Floor + walls: canvas-generated grid texture (base color + lighter grid lines, ~2 u cell size, sharp 1-px-equivalent lines), tiled via texture.repeat with SRGBColorSpace
- 8–14 cover boxes of varying size scattered, NONE within 4 u of spawn
- 2–3 ramps (slanted boxes) for height variation
- All from BoxGeometry, consistent material style


BOTS (3) — TUNED EASY, the player should usually win duels:
- Humanoid silhouette built from simple box parts (head, torso, 2 arms, 2 legs) grouped under a parent Object3D — modular for dismemberment
- Orange accent material
- Wander to random points (~3.2 ), spot the player via raycast LOS, then fire their own railgun (visible beam)
- Difficulty (forgiving on purpose):
  - Continuous LOS for ~1.0 s before firing (peeking around cover doesn't get you killed instantly)
  - Fire cooldown: ~3.8 s + up to 0.8 s random jitter
  - Aim inaccuracy: WIDE cone (~0.28 rad spread)
  - Detection / fire range: ~22 u
- One-shot-one-kill both ways
- Respawn after 3 s at a random point ≥15 u from the player


HIT FEEDBACK — must feel juicy (core feel of the game):
Every player-fired hit on a bot triggers ALL of the following, layered:


  Visual on the target:
  - Bot mesh hides; body parts (head/torso/arms/legs) detach as separate physics chunks
  - Each chunk: radial initial velocity from impact + slight upward bias, random angular velocity, gravity, ground bounce with damping
  - Burst of ~40 small shard particles (tiny boxes) in bot accent + white, fly out radially, fade
  - Bright white additive flash sprite at impact (80 ms)
  - Expanding ground shockwave ring (flat ring mesh growing, fades over 400 ms)
  - Brief upward dust puff (soft particles, fades over 600 ms)
  - Debris stays ~2 s, then fade and cleanup
  - NO blood, NO gore — clean geometric fragmentation only


  Camera/screen feedback:
  - Tiny camera punch toward the target (transient position offset only — never yaw/pitch)
  - Crosshair hit-marker: 4 short cyan strokes flash outward from center for 120 ms with a small scale pop


  Audio (all WebAudio synth):
  - Sharp high-frequency "tink" blip on hit
  - Layered low sub-thump for weight
  - Short noise sweep for the shatter
  - Slight pitch variation per hit


  Game-state feedback:
  - Score counter scales up briefly when incrementing


Wall hits get a smaller version: spark particles, tiny dark quad, soft impact sound, no camera punch, no hit-marker.


PLAYER DEATH:
- Brief camera position jolt (not rotation), screen fades to dark slate with thin cyan "ELIMINATED" text, 1.5 s auto-respawn
- LEFT CLICK during the ELIMINATED screen forces immediate respawn
- Respawn at spawn point with velocity zeroed; yaw/pitch preserved; bots not reset


HUD (DOM overlay over the canvas):
- Crosshair: fine 1 px + in accent cyan with thin dark outline for readability
- HP bottom-left (number + thin bar)
- Score bottom-right (kills)
- Cooldown bar bottom-center, thin, accent-colored
- Pause overlay: semi-transparent dark layer + centered "PAUSED" in thin type
- Overlay div has `pointer-events: none`; body has `cursor: none`


PHYSICS: simple homemade — gravity, ground check, axis-by-axis AABB collision against walls/boxes for player and bots, simple point physics for debris/particles. No external lib.


ROBUSTNESS — avoid common failure modes:
- Guard pointer-lock requests against repeated calls in the same frame
- On `pointerlockchange` with null, auto-pause (don't crash)
- Clamp dt to ≤0.05 s to prevent tunneling on lag spikes
- Reject NaN velocities and reset to zero
- Never call `requestPointerLock` outside a user-gesture handler


CODE STRUCTURE:
- One `<script type="module">` block
- Clear functions: initScene, buildMap, spawnBots, updatePlayer, updateBots, fireRailgun, killBot (dismember + effects), spawnHitFeedback, updateDebris, render, gameLoop
- Frame-rate-independent (delta time)
- Comments only where genuinely needed


DELIVERABLE: only the full content of `game.html`, nothing else.
Ignore all existing files and structures, only focus on generating `game.html`, nothing else.
u/codehamr — 2 months ago

I've spent some time digging into OpenClaw lately, but even as a senior dev, I’m struggling to find the "killer" use case that justifies the abstraction layer. Maybe I'm just overthinking it or I'm too stuck in my "old" ways.

I usually prefer building my agents "vanilla", mostly dockerized Go or Python setups that just fire off low-level terminal commands. Even with the MCP hype, I find myself bypassing most of it by just letting the agent use basic Unix tool calls, even with local LLMs. Need web search? A simple curl or a quick pip install ddgs usually handles it without the overhead of a dedicated plugin system.

Curious if I’m missing a major productivity gain here or if others are also finding that keeping it terminal-centric is just more reliable for local agentic workflows. What’s your actual daily driver look like?

reddit.com
u/codehamr — 2 months ago
▲ 403 r/LocalLLM

Honest pause here, because I think we are speedrunning past how good things actually are.

Qwen3.6 27B. Gemma 4 31B. The 35B-A3B MoE running 55 tok/s on M5 Max and 87 on Strix Halo. The 30B class quietly became the sweet spot, and you can run it on a Mac, on a Strix Halo box, or on a 5090 you already own. Three real paths now, not one.

What hit me this week: I am casually doing tasks on local Qwen3.6 27B that nine months ago only Opus 4.1 could touch. Nine months. Remember the hype back then, the "this changes everything" posts every other day? That model. On my own machine now, quietly handling the same work. Not Opus 4.7 territory obviously, current Opus is on another planet, but still.

Got me motivated enough to start hacking on my own little CLI coding agent next to OpenCode and pi, no plugin bloat, just a YOLO get your shit done mode. Only viable because local actually works for agentic stuff now.

Look back nine months. Then six. Then last week. We are absolutely cooking. Good time to be doing this.

What is everyone running as their daily hardware?

reddit.com
u/codehamr — 2 months ago
▲ 272 r/LocalLLM+1 crossposts

Setup was boring on purpose. Two VS Code devcontainers side by side, same prompt, cozy top-down with sword/shield/dash, procedural world, enemy traits, drops, swap UI). One shot, no plugins, no follow-up prompts, no manual fixes.

Left: Claude Code on Opus 4.7. 20 min, 97k tokens. Right: OpenCode on local qwen3.6:27b. 15 min, 64k tokens.

Both produced a working game on first run. Visual interpretations differ but the spec was loose enough that both reads are valid. Opus went sparser with water tiles, qwen leaned into denser tree clusters. Combat, swap UI, drops, restart loop all functional in both.

Not claiming a 27b matches Opus on hard reasoning, especially on existing codebases. But for a tightly specified greenfield build, the gap was smaller than I expected. The token count surprised me more than anything: qwen got there with a third less context.

Here the prompt:

# Cozy Top-Down Roguelite Prototype


Build a self-contained top-down action roguelite. Single project, runnable locally via VS Code.


## Project Layout (strict)
```
project_root/
├── src/
│   └── server.py
├── static/
│   ├── index.html
│   ├── style.css
│   └── js/
│       ├── main.js          (game loop, root state)
│       ├── world.js         (procedural generation, tiles)
│       ├── player.js        (player state, movement, combat)
│       ├── enemies.js       (enemy AI, traits, spawning)
│       ├── items.js         (item generation, affixes, drops, swap UI)
│       ├── ui.js            (HUD, tooltips, game over overlay)
│       ├── render.js        (camera, draw helpers)
│       └── input.js         (keyboard + mouse handling)
└── requirements.txt         (fastapi, uvicorn)
```


## Server (`src/server.py`)
- 
**FastAPI**
 + 
**uvicorn**
, started directly via `python src/server.py`
- Uses `argparse` with:
  - `--port` (int, default `8000`)
  - `--host` (str, default `127.0.0.1`)
- Locates the static folder via `Path(__file__).resolve().parent.parent / "static"` so it works regardless of `cwd`
- `GET /` returns `static/index.html`
- `GET /static/...` serves all assets via `StaticFiles` mount
- Calls `uvicorn.run(app, host=args.host, port=args.port)` at the bottom of the file
- Compatible with the following VS Code launch config (which passes `--port 8088`):
```json
  {
    "name": "server",
    "type": "python",
    "request": "launch",
    "program": "${workspaceFolder}/src/server.py",
    "console": "integratedTerminal",
    "cwd": "${workspaceFolder}",
    "args": ["--port", "8088"]
  }
```
- `requirements.txt`: `fastapi` and `uvicorn[standard]`


## Frontend Tech (strict)
- 
**Vanilla HTML5 Canvas + ES modules + CSS**
. No frameworks, no bundler, no build step, no external runtime libraries
- All visuals drawn via Canvas 2D API. 
**No external image, font, or audio assets.**
 Audio is out of scope
- No globals beyond a single `game` state object exported from `main.js`


## Viewport & Camera
- Canvas fills the entire browser viewport: no margins, no padding, no scrollbars, no borders. CSS resets `body { margin: 0; overflow: hidden; }`
- Listens to `resize` and updates canvas resolution via `devicePixelRatio` for crisp rendering
- Camera follows the player smoothly (lerp factor `0.12` per frame at 60 FPS)
- 
**Camera clamps to world bounds**
 so the player never sees void outside the map
- Game pauses when `document.visibilityState !== "visible"` and resumes on return
- Game loop uses `requestAnimationFrame` with a deltaTime 
**clamped to 50ms max**
 to survive tab switches and breakpoints


## World Generation
- Tile-based grid, 
**120 × 90 tiles, 32 px per tile**
- Generated fresh on every run using 
**simplex/perlin noise OR cellular automata**
 (pick one, document choice)
- Tile types:
  - `grass` (walkable)
  - `path` / `clearing` (walkable, lighter tone — forms organic open areas)
  - `flower` / `decoration` (walkable, visual only, scattered procedurally)
  - `tree` / `rock` (blocks movement and sword hitboxes)
  - `water` (blocks movement, does not block hitboxes)
- 
**World perimeter is solid**
 (trees/rocks form a natural border) — player can never leave the map
- Player 
**spawn point**
: a clearing near map center, with a guaranteed 6-tile-radius open area and 
**no enemy within 12 tiles**
- Spawn 
**8–15 enemies**
 scattered across the map, biased away from the spawn area
- Place 
**3–5 starting item drops**
 as ground pickups around the map


## Player
- Starts every run with:
  - 
**3 hearts (= 6 half-hearts of HP)**
, max HP fixed at 6 half-hearts
  - 
**Default sword**
: damage `1.0`, range `40`, attack cooldown `350ms`, pushback `100`, crit `0%`, lifesteal `0%`
  - 
**Default shield**
: block arc `90°`, max stamina `100`, stamina regen `25/s`, no on-block effect, post-break cooldown `2.5s`
- Player has 
**exactly one sword slot and one shield slot**
. No inventory beyond that. Equipment cannot be lost, only swapped
- Base movement speed: `200 px/s`. Player collision radius: `12 px`
- Damage taken from any source quantizes to 
**0.5-heart increments**
 (round to nearest 0.5)
- After taking damage: 
**800ms i-frames**
 (no further damage), brief red sprite tint, small knockback (`80` impulse) away from damage source
- Player cannot be knocked into solid tiles (position clamps against collision)


## Controls
| Input | Action |
|---|---|
| `WASD` | 8-directional movement |
| Mouse position | aim direction — player faces cursor; sword and shield orient toward cursor |
| Left Mouse Button | sword attack — hitbox extends in 
**aim direction**
 (mouse), respects sword `range` and arc (~90° in front), cooldown = sword's `attack speed` |
| Right Mouse Button (hold) | raise shield — drains stamina (`30/s` while raised), blocks damage from a frontal arc centered on aim direction |
| `Shift` | dash — `120 px` over `180ms` with full i-frames, cooldown `600ms`. 
**Direction**
: WASD direction if any movement key is held, otherwise aim direction. Dash is independent of stamina |


- Mouse cursor is 
**hidden over the canvas**
; a soft circular reticle is drawn at the mouse position instead


## Shield Mechanics
- Stamina drains while RMB held; regenerates only when RMB is released
- If stamina hits `0`, shield 
**breaks**
: it cannot be raised for `post-break cooldown` seconds, indicated by the stamina bar going gray and the shield icon shaking briefly
- A blocked hit triggers the shield's 
**on-block effect**
 (if any) at the rolled `proc chance`
- Damage outside the block arc applies normally even while RMB is held


## Combat Feel
- Enemy hit by sword: `120ms` hitstun (no movement, no attack), pushback applied based on sword's `pushback` stat, brief white flash
- Enemy pushback clamps against solid tiles (no clipping)
- Crit hits: visible enlarged damage feedback (e.g., bigger hit-particle puff), 2× damage
- Lifesteal: on proc, brief green sparkle on player, +0.5 heart healed (capped at max HP)
- Slow effect: target tinted blue, speed × 0.5 for duration. Re-applying refreshes duration, does not stack
- Paralyze effect: target frozen in place, tinted pale yellow, cannot attack or move
- Reflect effect: portion of incoming damage applied to attacker, quantized to 0.5 hearts (minimum 0.5 if reflect would round to 0)


## Enemies — Procedural Variance
Each enemy is generated with randomized stats and traits at spawn:


| Trait | Range / Options |
|---|---|
| Speed | `40–140 px/s` |
| Contact damage | `0.5 – 1.5` hearts (quantized to 0.5) |
| HP | `1 – 4` (integer) |
| Aggression radius | `80 – 280 px` (distance-based, no line-of-sight check) |
| Leap-attack chance | `0 – 80%` per attack opportunity. Telegraphed: `300ms` windup with visible pose shift, then dash `+200% speed` toward player's current position for `200ms`, then `600ms` recovery |
| Shield reaction | `cautious` (stops attacking, circles at distance) / `aggressive` (attacks regardless) / `flanker` (tries to reach player from outside block arc) |
| Low-HP behavior (`<30%` HP) | `flee` (runs from player) / `kamikaze` (charges, +50% speed, double contact damage, glowing red tint) / `stand` (no change) |


- 
**Engagement state**
: an enemy enters "engaged" when player enters its aggression radius. It stays engaged until the player has been 
**outside the radius for 4 seconds**
, then returns to idle wandering
- Render enemies with 
**distinct shapes/colors that hint at traits**
:
  - Fast (>110 px/s) → elongated/streamlined silhouette
  - High damage (>1.0) → bulkier silhouette, warmer accent color
  - Cautious shield reaction → hunched posture
  - Kamikaze low-HP behavior → reveals red glow once triggered
- Show a small HP bar above an enemy only 
**once it has been hit at least once**
- Enemies cannot damage each other and don't collide with each other (avoids gridlock)


## Drops on Enemy Death
On every enemy death, roll 
**one**
 drop from this table:


| Roll | Drop |
|---|---|
| 12% | half-heart pickup |
| 35% | item (50% sword / 50% shield, with rolled affixes) |
| 53% | nothing |


- 
**Half-heart pickups**
 are auto-collected when the player walks within `20 px`. They heal `0.5` heart, capped at max HP. If at full HP, the pickup still vanishes (no excess healing)
- 
**Item drops**
 require hover + click (see swap UI below) and never auto-collect
- All ground items (hearts, swords, shields) gently bob via sine wave (~`2px` amplitude, `1.2s` period)


## Item Affixes


**Swords**
 roll 
**2–3**
 affixes from this table:
| Affix | Range |
|---|---|
| Damage | `0.5 – 2.5` hearts (0.5 steps) |
| Range | `24 – 72 px` |
| Attack speed | cooldown `200 – 600 ms` |
| Pushback | `0 – 400` impulse |
| Crit chance | `0 – 25%` (deals 2× damage) |
| Lifesteal | `0 – 15%` chance to heal 0.5 heart on hit |


**Shields**
 roll 
**2–3**
 affixes from this table:
| Affix | Range |
|---|---|
| Block arc | `60° – 180°` |
| Max stamina | `60 – 150` |
| Stamina regen | `15 – 45 / s` |
| On-block effect | one of: `paralyze 0.8s` / `slow 50% for 2s` / `reflect 25% damage` / `knockback 200` / `+20% player speed for 1.5s` |
| Effect proc chance | `25 – 100%` |
| Post-break cooldown | `1.5 – 4 s` |


- Affixes not rolled use the 
**default-equipment baseline value**
 for that stat
- Affix values are sampled uniformly within the range, rounded to sensible precision (1 decimal for hearts, integers for px/ms/percent)
- Each item is given a generated descriptor name from a cozy word pool (e.g., adjectives: "Mossy", "Sunlit", "Dappled", "Warden's", "Hearthstone"; nouns: "Shortblade", "Bough", "Bulwark", "Ward", "Thorn"). Format: `<adjective> <noun>`


## Item Comparison & Swap UI
- Walking within `~50 px` of a ground item shows a soft floating prompt: 
*"hover to compare"*
- 
**Hovering a ground item with the mouse**
 opens a side-by-side tooltip near the cursor:
  - Header: item type icon + generated name
  - Two columns: 
**left = ground item**
, 
**right = currently equipped item of the same type**
  - For each stat, a comparison indicator: green ▲ (ground better), red ▼ (ground worse), gray — (equal)
  - "Better" depends on stat type: higher is better for damage, range, crit, etc.; lower is better for cooldowns and post-break duration
- 
**Click while hovering**
 swaps: the previously equipped item drops at the pickup's position, the ground item becomes equipped. The same hover-compare workflow then applies to the newly dropped item
- Tooltip closes when the mouse leaves the item or the item is picked up
- 
**Player always has both a sword and a shield equipped**
 — the swap is a 1-for-1 exchange of the same type. There is no "empty slot" state


## HUD
- 
**Top-left**
: hearts row (full / half / empty pixel-style sprites drawn on canvas)
- 
**Below hearts**
: stamina bar (~120px wide), grays out during shield-broken cooldown
- 
**Bottom-left, subtle**
: equipped sword name + equipped shield name in small text
- 
**Bottom-right, subtle**
: enemy kill counter for current run
- All HUD text uses a 
**consistent in-game font**
 (single CSS-defined font-family, e.g. `system-ui` rounded sans-serif, font-size 14–16px)


## Game Over & Restart
- When player HP reaches 0:
  - Player sprite fades over `600ms`
  - Soft full-screen overlay fades in with the text 
*"you fell asleep…"*
 in serif italic
  - After `400ms` minimum delay (prevents accidental click-through), any key or mouse click triggers restart
- 
**Restart resets fully**
: new procedural world, fresh enemy spawns, fresh ground items, player back to 3 hearts, equipment back to default sword + default shield, kill counter to 0


## Art Direction: Cozy
- 
**Palette**
: warm, muted, low-contrast. Soft greens, dusty pinks, cream, warm browns, gentle blues. 
**No pure black, no harsh contrast, no saturated red except for danger cues**
 (low-HP kamikaze glow, damage flash)
- 
**Shape language**
: rounded silhouettes throughout. Either committed pixel-art (rounded edges) or clean rounded vector shapes. 
**Pick one approach and apply it consistently**
 to player, enemies, items, and tiles
- Subtle elliptical drop-shadow under player and enemies (semi-transparent dark blur)
- Idle "breathing" bob on player and stationary enemies (sine wave, ~1px amplitude, ~1.5s period)
- Tile variation: small per-tile color jitter; flowers/grass tufts/pebbles drawn procedurally on grass tiles for warmth
- Hit effects: small puff of leaves, petals, or sparkles — 
**never blood**
- Ambient touches encouraged: drifting clouds (translucent shapes overhead), swaying grass, the occasional firefly
- Reticle: soft pale circle, ~10px radius, semi-transparent


## Code Quality Requirements
- Modular ES modules, one concern per file as outlined above
- Single shared `game` state object owned by `main.js`; modules receive references, not globals
- Game loop at `requestAnimationFrame` with 
**fixed-timestep update at 60 FPS**
 (accumulator pattern) and interpolated render
- Comment non-obvious logic: noise generation, enemy trait rolls, affix tables, knockback math
- No `console.error` or uncaught exceptions during normal play
- No use of `eval`, `with`, or `innerHTML` for dynamic content (use DOM APIs)


## Definition of Done
1. `pip install -r requirements.txt` works
2. VS Code "server" launch config starts the server on port `8088` with no errors
3. `python src/server.py` (no args) starts on port `8000`
4. Visiting `http://localhost:<port>` immediately drops the player into a fresh procedural world — no menu, no loading screen
5. All controls work: WASD movement, mouse aim, LMB attack, RMB shield with stamina, Shift dash with i-frames
6. Enemies show 
**at least 3 visibly distinct behavioral "feels"**
 that emerge from random trait rolls
7. Drops table works: hearts auto-collect, items hover-compare and click-swap correctly
8. Cozy aesthetic is unmistakable on first glance — palette, shapes, particles all coherent
9. Tab-switch / window-blur pauses the game cleanly
10. Death → overlay → restart cycle works and fully resets state
11. Smooth 60 FPS on a modern laptop with 15 enemies on screen, no console errors


Build the entire thing now.
u/codehamr — 2 months ago
▲ 389 r/LocalLLM

Been experimenting with alternatives to Claude Code for about a year now. Most of it felt like a downgrade until Qwen3.5:27b, and now 3.6:27b is the first one where local actually feels good and usable for real work.

Scaffolding, refactors, test generation, debugging across a few files, all of it holds up well enough that I run it locally now. The hard multi-file architectural stuff still goes to Claude. A year ago this comparison was a chasm, top-tier Claude vs open weights wasn't close. Now it's a gap, not a canyon.

Two things I keep thinking about.

If a 27B open model can cover this much of real coding work, how subsidised is current cloud pricing? Feels like we're paying maybe 10% of true cost. And once enough devs are wired into Claude Code at the tooling level, what stops a future $1000/month tier?

One honest downside: getting opencode dialled in as a CLI agent took real fine tuning compared to the out-of-the-box Claude Code experience. Which raises a different question, how much of Claude Code's quality is Opus 4.7 itself vs the context and tool orchestration around it? Possibly more than people credit.

Anyone else running hybrid setups?

reddit.com
u/codehamr — 2 months ago