diff --git a/html/js/render/sceneModel.js b/html/js/render/sceneModel.js
index 99550e3..1b961fa 100644
--- a/html/js/render/sceneModel.js
+++ b/html/js/render/sceneModel.js
@@ -104,7 +104,9 @@
entrance: { char: '<', color: '#3fb950', solid: false },
exit: { char: '>', color: '#d29922', solid: false },
treasure: { char: '$', color: '#fbbf24', solid: false },
- torch: { char: 'i', color: '#d29922', solid: false, fx: 'fire', fxScale: 0.34 },
+ // The generator only places torches on WALL cells adjacent to floor, so the fixture is
+ // wall-mounted: base on `wall`, draw the torch sprite over it, then RK.fx animates the flame.
+ torch: { char: 'i', color: '#d29922', solid: false, over: 'wall', fx: 'fire', fxScale: 0.34 },
// Hazard zones. The base tile stays walkable/ground; RK.fx paints the pulsing overlay. These
// render as soon as the dungeon generator emits their chars (L/P/^) in the tile stream.
lava: { char: '≈', color: '#7a2a0e', solid: false, hazard: 'lava' },
diff --git a/html/js/render/tileRenderer.js b/html/js/render/tileRenderer.js
index 0b2914f..3d4b266 100644
--- a/html/js/render/tileRenderer.js
+++ b/html/js/render/tileRenderer.js
@@ -117,6 +117,13 @@
ctx.fillStyle = bdef.color || def.color;
ctx.fillRect(px, py, cell, cell);
}
+ // Fire fixtures (torch/hearth) carry a sprite — draw the sconce/torch tile over
+ // its base so it reads as a mounted FIXTURE, not a bare procedural flame; RK.fx
+ // then animates the flame + glow on top. Hazards (lava/poison/spikes) have no sprite.
+ if (def.fx === 'fire' && useAtlas) {
+ var fco = pickVariant(tmap[kind], x, y);
+ if (fco) atlas.draw(ctx, fco[0], fco[1], px, py, cell);
+ }
applyCellLight(ctx, scene, x, y, px, py, cell);
continue;
}