- scripts/touch_controls.gd: full-screen layer routing multi-touch by touch
index: floating joystick on the left half (analog move_* actions), look area
on the right half, FIRE/GRENADE/RELOAD/JUMP buttons. Shown automatically on
web_android/web_ios or a touchscreen; overridable with --touch/--no-touch and
?touch=1/?touch=0. The root Control uses MOUSE_FILTER_IGNORE on purpose: a
STOP control swallows the first click and the Web start gate never fires.
- scripts/player.gd: touch_mode disables mouse look and pointer lock; view
rotation moved to apply_look() shared by mouse and touch; reload and grenade
are polled now (is_action_just_pressed) like shoot/jump, because an
InputEventAction synthesised inside another event's dispatch does not reach
_unhandled_input; start_reload() extracted; get_vector uses an explicit 0.2
dead zone so the joystick keeps its full travel.
- scripts/main.gd: creates the layer when needed, accepts a screen touch as the
start gesture (which also unlocks browser audio) and enables the layer only
afterwards.
- tools/test_touch_controls.gd: 11 assertions (joystick movement, look
rotation, simultaneous multi-touch, fire hold/release, reload, grenade, jump,
detection) runnable headless and on a real display.
- docs/TOUCH-CONTROLS.md: detection rules, input model, verification.