- Iso & 3D character faced the wrong way: the SP game never sends player.facing (only the tavern
does) so it defaulted to down/SW. Both renderers now INFER facing from the movement delta they
already track (explicit e.facing still wins for the tavern).
- 3D could break the game: wrap ThreeRenderer construction (createRenderer) and the _animate RAF
body in try/catch — a 3D failure now falls back to Tiled / stops the loop instead of throwing.
- ASCII walls/floors were near-invisible (legend colours are near-black, tuned for tile fog): use
brighter glyph colours for wall/floor in ASCII (features keep their own colours).
3D built every tile including unexplored, revealing the whole map. Now: _buildTiles skips
unexplored (dark) cells so they never render (void), and the scene gets THREE distance Fog
(black, 14->32) which — since the camera follows the player — fades explored tiles to black away
from you. Background set to pure black to match. Entities are already fog-gated at the scene
level (features on seen, monster in-view). Net: unexplored hidden, explored fades with distance,
no map-edge leak — matching the 2D modes.
3D is a paid rung and should behave like the other modes. Rework the THREE camera to FOLLOW the
player instead of framing the whole level: canvas now sizes to the host (setSize updateStyle),
the ortho frustum is a fixed player-centered zoom (span 8) with host aspect, and _animate re-targets
the camera to the player world position every frame (keeps the iso (8,9,8) offset; glides smoothly
since the player mesh lerps). SP._applyCamera no longer CSS-transforms the 3D canvas (it fills the
host and THREE owns the camera). Handles host resize via _fitToHost.