- Camera zoom: +/- keys adjust cell size 4-24px, grid_w/h recalculated
Works in both graphics and ascii renderers via GpuRenderer trait
- Day/night cycle: ambient_light_at_tick() modulates brightness by sine
Applied to terminal renderer (CPU lighting path)
- Tooltip: shows material name + temperature at mouse cursor position
Tracked via CursorMoved event, world coords computed from screen pos
- Crosshair: dotted line from player to mouse cursor, fading alpha
Shows aiming trajectory for projectile combat
All 185 tests + 14 scenarios pass. 162 FPS benchmark.
Spectrum system (src/ai/spectrum.rs):
- 6 spectrums: materials, temperature, light, entities, density, velocity
- Each renders a different ASCII view of the same world state
- materials: material display chars + entity chars
- temperature: heat levels as .-=+oxX#
- light: brightness as .:+oO*
- entities: entity positions only, background dots
- density: material density as .:+oO#
- velocity: entity speed + CA activity as .:+oO,
Tape recording (src/ai/tape.rs):
- --mode tape CLI with --tape-interval, --tape-output, --tape-json
- Records all 6 spectrums + world state every N ticks
- Each frame: tick, depth, kills, score, camera, player HP/pos, entity count
- Outputs human-readable text and JSON formats
Pipe protocol additions:
- get_spectrum: single spectrum view by name
- get_all_spectrums: all 6 spectrums in one response
- Response.spectrums field added
Architecture priorities updated:
- Graphics mode is PRIMARY renderer
- ASCII mode is DEBUG backend
- Terminal mode is LEGACY
- AI uses multi-spectrum ASCII layers for observation
All 171 tests + 14 scenarios pass.
Character detail:
- Player: 68 body parts (was 42) — eyes, hair, cape, hat, gloves
- Goblin: 56 body parts (was 39) — red eyes, pointed ears, teeth, skin tones
- New body labels: eye, hair, cape, tooth, ear
- Updated preview_ascii label map for new part types
Mouse aiming (Noita-style):
- Track mouse position via CursorMoved events
- Track left-click via MouseInput events
- Left-click shoots projectile toward mouse cursor direction
- Player faces left/right based on mouse X relative to player screen X
- Keyboard shoot (hjkl) still works as fallback
- Player.facing_right field added
- WindowInput: mouse_x, mouse_y, mouse_left, shoot_mouse fields
- on_mouse_move(), on_mouse_button() handlers
- clear_keys() also clears mouse state on focus loss
All 171 tests + 14 scenarios pass.