LMB-hold strokes a line of paints (Auto-Tile: each hovered vertex; Direct: each hovered cell as an override). RMB-hold strokes a line of erases (clear_vertex / clear_override). On mouse-press inside the UI (toolbar / palette / side-panel) the drag never enters paint-mode so toolbar interaction stays unaffected. State machine: - press(button) outside UI -> drag_paint = "paint"|"erase" - while drag_paint and corresponding button still down -> dispatch paint at current snap_vertex / mouse_cell each frame - button release -> drag_paint = nil Idempotency: maps.set_vertex / set_override / clear_* are no-op when the target state is unchanged, so the per-frame repaint is cheap and doesn't grow the JSON on save.
527 B
527 B